在应用开发中每一个按钮或者需要点击的图片我们都应该至少呈现两种状态state_pressed和normal,友好的提示用户现在按下了哪个View,对于View通常我们会使用两张图片来实现一个Selector。所以我在想是否能像微信那样每个View的背景可以不一致,但是却又通用的点击效果呢,所以查查一些资料,自己总结了一下写了这么一个Demo来实现通用的点击效果。
首先取得每一个View的Drawable,调用该Drawable的setColorFilter方法,那么我们需要了解一些setColorFilter中的PorterDuff.Mode工作原理:
PorterDuff.Mode为枚举类,一共有16个枚举值例如:PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
更多的变量可以查看:http://blog.csdn.net/t12x3456/article/details/10432935
1.自定义通用的ImageView
public class CommonImageView extends ImageView {
public CommonImageView(Context context) {
super(context);
}
public CommonImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private Drawable mDrawable;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDrawable = getDrawable();
mDrawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mDrawable.clearColorFilter();
break;
}
return super.onTouchEvent(event);
}
}
对于通用的ImageView我们不需要管图片是圆角、圆形、正方形均可以呈现点中的效果。
2.自定义通用的Button
public class CommonButton extends Button {
public CommonButton(Context context) {
super(context);
}
public CommonButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
private Drawable mDrawable;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDrawable = getBackground();
mDrawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mDrawable.clearColorFilter();
break;
}
return super.onTouchEvent(event);
}
}
对于Button一样不管什么样的背景图均可以实现想要的效果,但是针对android:background=“#ff4983”这样来给Button设置背景的时候很可惜是无效的:Setting a color filter on a ColorDrawable has no effect因为在ColorDrawable中文档有这种提示,所以在这种情况下只能把颜色写入到shape中然后使用shape当做背景即可。
3.源码思路:每一个View的均是在手势按下是变色,手势放开变回正常颜色,所以我们采用重写onToucEvent方法分别在ACTION_DOWN的时候给mDrawable.setColorFilter,在ACTION_UP的时候mDrawable.clearColorFilter来取消colorFilter变回原来的背景。
4.Demo的效果图:
5.xml代码中使用,其实跟平时的控件使用是一样的原理
<com.neacy.commonselector.CommonImageView
android:id="@+id/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
android:layout_marginTop="20dp"/>
ps:一开始在iOS上面看到为什么他们的按钮没有切两张背景图去能在按钮上面呈现一层灰色的按压效果?在Android也建议在onTouchEvent中实现按下效果,因为一个View上一下子呈现两张图片比较占用内存,用这种方式何不两全其美呢。