美文网首页
优雅实现点击View背景变化效果

优雅实现点击View背景变化效果

作者: 木棉_8d64 | 来源:发表于2019-06-01 10:35 被阅读0次

    起因

    基于现在应用里面大量通过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;

        }

    }

    相关文章

      网友评论

          本文标题:优雅实现点击View背景变化效果

          本文链接:https://www.haomeiwen.com/subject/pesotctx.html