Android使用RippleDrawable创建纹波效果长按View松开之后无法恢复View的背景色

前言

最近在使用纹波效果时遇到了一个小问题,使用RippleDrawable为View控件设置纹波效果,长按View控件松开之后View的背景色变为纹波的颜色,无法恢复未点击控件时的正常背景色。

首先看两张纹波的效果图

Android使用RippleDrawable创建纹波效果长按View松开之后无法恢复View的背景色_第1张图片
正常的纹波效果图
Android使用RippleDrawable创建纹波效果长按View松开之后无法恢复View的背景色_第2张图片
不正常的纹波效果图

首先我们长按设置了纹波效果的View控件,正常情况下在纹波效果结束之后松开手指View的背景色会恢复成原来的颜色,而不正常情况下松开手指之后背景色并没有恢复。

下面我们看一下纹波异常时的代码

  • res/drawable-v21/item_selector.xml


    

  • res/layout/activity_main.xml



    

        
    

  • MainActivity.java
package rich.ivan.rippledrawable;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnLongClickListener {

    @Override    
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main);
        LinearLayout layout = (LinearLayout) findViewById(R.id.test);
        layout.setOnClickListener(this);
        layout.setOnLongClickListener(this);                      
    }    

    @Override    
    public void onClick(View view) {    
    
    }    

    @Override    
    public boolean onLongClick(View view) {
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override                                    
            public boolean onTouch(View view, MotionEvent motionEvent) {                  
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_UP:
                        // intercept touch event
                        return true;
                }
                return false;
            }
        });
        return false;
    }
}

纹波出现异常的原因

经过我的测试,发现了纹波出现异常的原因。在监听View长按事件的同时监听View的触摸事件,在OnTouchListener的MotionEvent.ACTION_UP事件中返回了true,会导致纹波松开手指之后View无法恢复正常的背景色。如果返回false或者使用默认的返回操作,纹波效果就能正常显示。不过我目前并没有搞懂这个问题的原理是什么,还请了解原理的简友们指点一下。

异常代码:

switch (motionEvent.getAction()) {
    case MotionEvent.ACTION_UP:
        // intercept touch event
        return true;
}

正常代码:

switch (motionEvent.getAction()) {
    case MotionEvent.ACTION_UP:
        // do not intercept touch event
        return false;
}

总结

使用RippleDrawable创建纹波效果时,如果View既需要监听长按事件又要监听用户的手势操作,在OnTouchListener的onTouch方法中处理手势时如果返回了true,拦截了当前的点击事件,会造成设置纹波效果的View控件背景色无法恢复正常。

你可能感兴趣的:(Android使用RippleDrawable创建纹波效果长按View松开之后无法恢复View的背景色)