前言
最近在使用纹波效果时遇到了一个小问题,使用RippleDrawable为View控件设置纹波效果,长按View控件松开之后View的背景色变为纹波的颜色,无法恢复未点击控件时的正常背景色。
首先看两张纹波的效果图
首先我们长按设置了纹波效果的View控件,正常情况下在纹波效果结束之后松开手指View的背景色会恢复成原来的颜色,而不正常情况下松开手指之后背景色并没有恢复。
下面我们看一下纹波异常时的代码
- res/drawable-v21/item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorAccent">
<item android:drawable="@color/colorNormalBg"/>
</ripple>
- res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/test"
android:layout_width="match_parent"
android:layout_height="75dp"
android:layout_margin="16dp"
android:background="@drawable/item_selector"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="#212121"/>
</LinearLayout>
</LinearLayout>
- 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控件背景色无法恢复正常。