起因
基于现在应用里面大量通过selector去实现点击效果,即需要多创建一个xml文件,又需要视觉多给2张图,所以,现统一管理,为了后期的快速开发,以及视觉快速出图,还有整个应用的点击效果规范,现自定义两个View,分别是GrayTextView和GrayImageView,来实现需要的点击背景的效果。
核心思想:
setColorFilter+PorterDuff.Mode搭配使用
GrayTextView
自带属性
before_select_color 表示点击之前的背景颜色(设置background就行)
after_select_color 表示点击之后的背景颜色
duff_mode PorterDuff.Mode模式(按需选择模式)
使用步骤:
<com.xtc.common.widget.clickeffect.GrayTextView
android:id="@+id/btn_new_contact_no_more_remind"
android:background="@drawable/no_remind_btn_bg_selector"
android:layout_width="80dp"
android:layout_height="36dp"
gray_view:before_select_color="#f95c06"
gray_view:after_select_color="#99f95c06"
GrayImageView
自带属性
before_select_color 表示点击之前的背景颜色(设置src或background就行)
after_select_color 表示点击之后的背景颜色
duff_mode PorterDuff.Mode模式(按需选择模式)
使用步骤:
<com.xtc.common.widget.clickeffect.GrayImageView
android:id="@+id/btn_new_contact_no_more_remind"
android:background="@drawable/no_remind_btn_bg_selector"
android:layout_width="80dp"
android:layout_height="36dp"
gray_view:before_select_color="#f95c06"
gray_view:after_select_color="#99f95c06"
案例:(GrayImageView)
现在的点击效果实现方式
<ImageView
android:id="@+id/iv_cancle_take_photo"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/chat_ic_media_cancel"/>
自定义一个drawable,命名:chat_ic_media_cancel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/chat_ic_media_cancel_default"
android:state_pressed="false"/>
<item android:drawable="@drawable/chat_ic_media_cancel_click"
android:state_pressed="true"/>
</selector>
所需要的图片资源
选中前:
选中后:
最终效果:
用GrayImageView实现(所用模式:PorterDuff.Mode.MULTIPLY)
<com.xtc.common.widget.clickeffect.GrayImageView
android:id="@+id/iv_cancel_take_photo"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/chat_ic_media_cancel_default"/>
</LinearLayout>
所需要的图片资源:
仅需要选中前的:
最终效果:
效果是一样的,已给视觉验收。
duff_mode模式的选择
PorterDuff.Mode.MULTIPLY 该模式表示两个图片叠加后的效果(用于大部分点击背景变化的场景)
PorterDuff.Mode.DST_ATOP 表示两个图片叠加后的效果以及图片二混在一起(更多列表,所有开关图片的前后变化)
其他模式,可以根据具体场景来选择。
GrayImageView主要代码:
package com.xtc.common.widget.clickeffect;
/**
* author: ldf
* date: 2019/3/2 & 14:41
* version 1.0
* description
* modify by
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import com.xtc.common.R;
public class GrayImageView extends AppCompatImageView implements GestureDetector.OnGestureListener {
/**
* 监听手势
*/
private GestureDetector mGestureDetector;
private Integer mDuffMode;
private int mBeforeSelectColor;
private int mAfterSelectColor;
public GrayImageView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, this);
init(attrs);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.GrayImageView);
mDuffMode = array.getInteger(R.styleable.GrayImageView_duff_mode, 0);
mBeforeSelectColor = array.getColor(R.styleable.GrayImageView_before_select_color, Color.WHITE);
mAfterSelectColor = array.getColor(R.styleable.GrayImageView_after_select_color, 0xFFebebeb);
array.recycle();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//在cancel里将滤镜取消,注意不要捕获cacncel事件,mGestureDetector里有对cancel的捕获操作
//在滑动GridView时,AbsListView会拦截掉Move和UP事件,直接给子控件返回Cancel
if (event.getActionMasked() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
removeFilter();
}
return mGestureDetector.onTouchEvent(event);
}
/**
* 设置滤镜
*/
private void setFilter() {
//先获取设置的src图片
Drawable drawable = getDrawable();
//当src图片为Null,获取背景图片
if (drawable == null) {
drawable = getBackground();
}
if (drawable != null) {
//设置滤镜
drawable.setColorFilter(mAfterSelectColor, getImageMode(mDuffMode));
}
}
/**
* 清除滤镜
*/
private void removeFilter() {
//先获取设置的src图片
Drawable drawable = getDrawable();
//当src图片为Null,获取背景图片
if (drawable == null) {
drawable = getBackground();
}
if (drawable != null) {
//清除滤镜
drawable.clearColorFilter();
}
}
@Override
public boolean onDown(MotionEvent e) {
setFilter();
//这里必须返回true,表示捕获本次touch事件
return true;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
removeFilter();
performClick();
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//长按时,手动触发长安事件
performLongClick();
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
/**
* 根据传入的不同mode值设置对应的PorterDuff.Mode
*
* @param modeInt
* @return
*/
private PorterDuff.Mode getImageMode(int modeInt) {
PorterDuff.Mode mode;
switch (modeInt) {
case 1:
mode = PorterDuff.Mode.MULTIPLY;
break;
case 2:
mode = PorterDuff.Mode.DST_ATOP;
break;
case 3:
mode = PorterDuff.Mode.SRC_ATOP;
break;
default:
mode = PorterDuff.Mode.MULTIPLY;
break;
}
return mode;
}
}
网友评论