首页 > 代码库 > Android:通过滤镜实现点击图片变暗效果

Android:通过滤镜实现点击图片变暗效果

实现点击图片(ImageView)变暗效果,有一个较简单的方法,就是讲目标图片设置为背景图片(setBackground),再创建一个selector.xml文件,里面放置一张普通状态时的透明图片,一张点击状态下的棕色半透明图片,将其设置为ImageView的源图片。这样在点击ImageView时,源图片会变换透明度,达到变暗效果。但这种方法有个缺点:由于源图片已经被限制死了,假如我们需要自定义背景图片,将目标图片放置在背景图片上,就无法实现了。这里介绍一种通过滤镜和监听onTouchEvent事件来达到变暗效果的方法。

源码如下:

import android.content.Context;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.ImageView;/**  * @ClassName: ThumbnailView  * @Description:  点击时显示明暗变化(滤镜效果)的ImageView * @author LinJ * @date 2015-1-6 下午2:13:46  *   */public class ThumbnailView extends ImageView{    public ThumbnailView(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getActionMasked()) {        case MotionEvent.ACTION_DOWN:            //在按下事件中设置滤镜            setFilter();            break;        case MotionEvent.ACTION_UP:            //由于捕获了Touch事件,需要手动触发Click事件            performClick();        case MotionEvent.ACTION_CANCEL:            //在CANCEL和UP事件中清除滤镜            removeFilter();            break;        default:            break;        }        return true;    }    /**       *   设置滤镜     */    private void setFilter() {        //先获取设置的src图片        Drawable drawable=getDrawable();        //当src图片为Null,获取背景图片        if (drawable==null) {            drawable=getBackground();        }        if(drawable!=null){            //设置滤镜            drawable.setColorFilter(Color.GRAY,PorterDuff.Mode.MULTIPLY);;        }    }    /**       *   清除滤镜     */    private void removeFilter() {        //先获取设置的src图片        Drawable drawable=getDrawable();        //当src图片为Null,获取背景图片        if (drawable==null) {            drawable=getBackground();        }        if(drawable!=null){            //清除滤镜            drawable.clearColorFilter();        }    }}

通过监听Down事件设置滤镜,监听Up和Cancel事件去掉滤镜,以此达到图片变暗效果。但是这个方法也有个很麻烦的缺点:由于拦截了Touch事件,会导致onClick和onLongClick事件还有其他很多事件都无法正常触发,如上述代码所示需要手动触发Click事件。当该View是作为ListView的内部View时,情况将更加麻烦,因此要慎用,在需要复杂交互的情况下最好别用这种方法。

修改添加长按事件:

 

package com.linj.camera.view;import android.content.Context;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.widget.ImageView;/**  * @ClassName: FilterImageView  * @Description:  点击时显示明暗变化(滤镜效果)的ImageView * @author LinJ * @date 2015-1-6 下午2:13:46  *   */public class FilterImageView extends ImageView implements GestureDetector.OnGestureListener{        /**   监听手势*/     private GestureDetector mGestureDetector;    public FilterImageView(Context context, AttributeSet attrs) {        super(context, attrs);        mGestureDetector=new GestureDetector(context, this);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        //在cancel里将滤镜取消,注意不要捕获cacncel事件,mGestureDetector里有对cancel的捕获操作         //在滑动GridView时,AbsListView会拦截掉Move和UP事件,直接给子控件返回Cancel        if(event.getActionMasked()== MotionEvent.ACTION_CANCEL){            removeFilter();        }        return mGestureDetector.onTouchEvent(event);    }    /**       *   设置滤镜     */    private void setFilter() {        //先获取设置的src图片        Drawable drawable=getDrawable();        //当src图片为Null,获取背景图片        if (drawable==null) {            drawable=getBackground();        }        if(drawable!=null){            //设置滤镜            drawable.setColorFilter(Color.GRAY,PorterDuff.Mode.MULTIPLY);;        }    }    /**       *   清除滤镜     */    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) {        // TODO Auto-generated method stub    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        removeFilter();        performClick();            return false;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,            float distanceY) {        // TODO Auto-generated method stub        return false;    }    @Override    public void onLongPress(MotionEvent e) {        //长安时,手动触发长安事件        performLongClick();    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,            float velocityY) {        // TODO Auto-generated method stub        return false;    }}

 

Android:通过滤镜实现点击图片变暗效果