Android,自定义一个点击变暗效果的ImageView

一、前言

       大家可能很多地方要用到一个点击变暗效果的ImageView,之前我想了两种解决方案,但是这两种方法都不好,但是还是提一提吧。

       方案一:把ImageView的background设置为我们要的图片,src就设置一个drawable(被点击之后换成50%灰度的一个drawable)

                     方案一的弊端就是为了达到这种效果,我们的src被占用了。

       方案二:用两层ImageView,上面的ImageView的background或者src设置为一个【被点击之后换成50%灰度的一个drawable】

                     方案二的弊端就是增加了GPU的渲染速度,为了绘制一张图要绘制两层,完全没必要。

       

二、正文

       最后我就想办法自定义了一个ImageView,就特意去看了View.java的源码(ImageView继承View),想看看View被点击之后是如何更换drawable不同状态的图片。

       在View的onTouchEvent()方法(大家都知道这个方法是处理触摸事件的方法吧)里面有这么一段代码

       

case MotionEvent.ACTION_DOWN:
                    mHasPerformedLongPress = false;

                    if (performButtonActionOnTouchDown(event)) {
                        break;
                    }

                    // Walk up the hierarchy to determine if we're inside a scrolling container.
                    boolean isInScrollingContainer = isInScrollingContainer();

                    // For views inside a scrolling container, delay the pressed feedback for
                    // a short period in case this is a scroll.
                    if (isInScrollingContainer) {
                        mPrivateFlags |= PFLAG_PREPRESSED;
                        if (mPendingCheckForTap == null) {
                            mPendingCheckForTap = new CheckForTap();
                        }
                        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                    } else {
                        // Not inside a scrolling container, so show the feedback right away
                        setPressed(true);
                        checkForLongClick(0);
                    }
                    break;

这段代码的大概意思就是case: MotionEvent.ACTION_DOWN,按下去的时候事件发生时,检测View是否被点击了,如果点击了就setPressed(true);把状态标记为已点击

那么对应的case: MotionEvent.ACTION_UP,松开手的时候会检测是否是unpressed,如果是就setPressed(false);把状态标记为未点击

关键点来了,就是setPress(boolean pressed)这个方法,定义如下

    /**
     * Sets the pressed state for this view.
     *
     * @see #isClickable()
     * @see #setClickable(boolean)
     *
     * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts
     *        the View's internal state from a previously set "pressed" state.
     */
    public void setPressed(boolean pressed) {
        final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);

        if (pressed) {
            mPrivateFlags |= PFLAG_PRESSED;
        } else {
            mPrivateFlags &= ~PFLAG_PRESSED;
        }

        if (needsRefresh) {
            refreshDrawableState();
        }
        dispatchSetPressed(pressed);
    }
如果穿进去的参数pressed是true的话,首先会判断一下是否需要更新drawable的状态。然后就根据传进来的参数pressed做相应的drawable视图变更。


那么现在就很好办了,我们只要重写setPressed(boolean pressed)这个方法就行了,当传进来的pressed是true的时候我们就改变ImageView的背景图。

**
* Created by minghao_zl on 14-9-17.
* 公共的蒙版ImageView(点击变暗效果)
*/
public class MaskableImageView extends ImageView{

    private boolean touchEffect = true;
    public final float[] BG_PRESSED = new float[] { 1, 0, 0, 0, -50, 0, 1,
            0, 0, -50, 0, 0, 1, 0, -50, 0, 0, 0, 1, 0 };
    public final float[] BG_NOT_PRESSED = new float[] { 1, 0, 0, 0, 0, 0,
            1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 };

    public MaskableImageView(Context context) {
        super(context);
    }

    public MaskableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MaskableImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setPressed(boolean pressed) {
        updateView(pressed);
        super.setPressed(pressed);
    }

    /**
     * 根据是否按下去来刷新bg和src
     * created by minghao.zl at 2014-09-18
     * @param pressed
     */
    private void updateView(boolean pressed){
        //如果没有点击效果
        if( !touchEffect ){
            return;
        }//end if
        if( pressed ){//点击
            /**
             * 通过设置滤镜来改变图片亮度@minghao
             */
            this.setDrawingCacheEnabled(true);
            this.setColorFilter( new ColorMatrixColorFilter(BG_PRESSED) ) ;
            this.getBackground().setColorFilter( new ColorMatrixColorFilter(BG_PRESSED) );
        }else{//未点击
            this.setColorFilter( new ColorMatrixColorFilter(BG_NOT_PRESSED) ) ;
            this.getBackground().setColorFilter(
                    new ColorMatrixColorFilter(BG_NOT_PRESSED));
        }
    }
}
其实很简单,我就在setPressed()方法里面根据传进来的参数pressed来处理视图改变的效果。updateView()方法里面也就是通过一个设置一个滤镜矩阵来改变灰暗度,我就不细说滤镜矩阵了。


~完了,不懂的可以留言噢,(*^__^*) 嘻嘻……





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值