起因
基于現(xiàn)在應用里面大量通過selector去實現(xiàn)點擊效果,即需要多創(chuàng)建一個xml文件,又需要視覺多給2張圖释涛,所以侮攀,現(xiàn)統(tǒng)一管理,為了后期的快速開發(fā)迎卤,以及視覺快速出圖拴鸵,還有整個應用的點擊效果規(guī)范,現(xiàn)自定義兩個View蜗搔,分別是GrayTextView和GrayImageView劲藐,來實現(xiàn)需要的點擊背景的效果。
核心思想:
setColorFilter+PorterDuff.Mode搭配使用
GrayTextView
自帶屬性
before_select_color 表示點擊之前的背景顏色(設(shè)置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 表示點擊之前的背景顏色(設(shè)置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)
現(xiàn)在的點擊效果實現(xiàn)方式
<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實現(xiàn)(所用模式: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 表示兩個圖片疊加后的效果以及圖片二混在一起(更多列表不同,所有開關(guān)圖片的前后變化)
其他模式厉膀,可以根據(jù)具體場景來選擇。
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 {
? ? /**
? ? * 監(jiān)聽手勢
? ? */
? ? 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);
? ? }
? ? /**
? ? * 設(shè)置濾鏡
? ? */
? ? private void setFilter() {
? ? ? ? //先獲取設(shè)置的src圖片
? ? ? ? Drawable drawable = getDrawable();
? ? ? ? //當src圖片為Null百新,獲取背景圖片
? ? ? ? if (drawable == null) {
? ? ? ? ? ? drawable = getBackground();
? ? ? ? }
? ? ? ? if (drawable != null) {
? ? ? ? ? ? //設(shè)置濾鏡
? ? ? ? ? ? drawable.setColorFilter(mAfterSelectColor, getImageMode(mDuffMode));
? ? ? ? }
? ? }
? ? /**
? ? * 清除濾鏡
? ? */
? ? private void removeFilter() {
? ? ? ? //先獲取設(shè)置的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) {
? ? ? ? //長按時饭望,手動觸發(fā)長安事件
? ? ? ? performLongClick();
? ? }
? ? @Override
? ? public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
? ? ? ? ? ? ? ? ? ? ? ? ? float velocityY) {
? ? ? ? return false;
? ? }
? ? /**
? ? * 根據(jù)傳入的不同mode值設(shè)置對應的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;
? ? }
}