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; } }