事件传递之二(实现简单的按下半透明效果)

我们知道使用Button或者ImageView,都可以给他们添加Selector实现样式

例如:

  

   

   

当按下的时候是红色,没有按下的时候是白色。


假设当我们的按钮显示的图片是网络图片时,但这个按钮又是可点击的按钮时,这时我们也需要为该按钮添加一个样式,我们将如何写呢?


如果大家了解IOS开发的话,IOS的UIButton系统按钮就可以做到一种叫蒙层的效果,意思是当按下按钮时,为该按钮添加一个蒙层,这个蒙层

是一个半透明的图层,非按下状态时,取消掉这个蒙层,即可实现按钮的蒙层样式。


为了实现这种蒙层效果,我们可以想到两种办法

1.使用两个ImageView处于同一层,底层放显示图片的ImageView,上层放自定义selector的样式,同样可以实现蒙层的效果

2.重写ImageView,在onTouchEvent重写事件,当处于Down时,setAlpha(透明值),当Up时,我们将其设置为setAlpha(0);即可,下面是继承ImageImage中重写onTouchEvent的代码段

	public boolean onTouchEvent(MotionEvent event) {
		boolean b = super.onTouchEvent(event);
		if(event.getAction()==MotionEvent.ACTION_DOWN){
			setAlpha(0.5f);
			postInvalidate();
		}else{
			setAlpha(1f);
			postInvalidate();
		}
		return b;
	}



       大家运行上述代码后,会发现一个问题,当按下的时候按钮会变成半透明效果,但是弹起Up事件后,图片依然是半透明,不能恢复原状,这是为什么呢?

原因很简单,那是因为当执行到

event.getAction()==MotionEvent.ACTION_DOWN、setAlpha()方法执行后,return 了false,根据文章 事件传递机之一(基础篇),可知,当Down后,如果返回false,则事件将不再继续传递下去,也就是事件不会再传递给Up/move等 ,所以一旦设置了setAlpha(0.5f),则不会再调用setAlpha(0),所以就出现了上述的问题,即不能实现弹起恢复的效果。

于是我就做了如下改动

	public boolean onTouchEvent(MotionEvent event) {
		//boolean b = super.onTouchEvent(event);
		if(event.getAction()==MotionEvent.ACTION_DOWN){
			setAlpha(0.5f);
			postInvalidate();
		}else{
			setAlpha(1f);
			postInvalidate();
		}
		return true;
	}

运行后,发现按下变半透明,弹起恢复正常。


但此代码依然有一个问题,当我们为此View添加setOnclickListener()监听时,发现不能触发点击事件了,那这又是为什么呢?


原因依然很简单,因为重写onTouchEvent后,我们没有调用super.onTouchEvent,而所有View的Click事件都是由super.onTouchEvent的事件机制判断点击事件的逻辑,而此处我们调用调用,即出现事件不能监听的情况,于是我又修改了一下代码如下:

	public boolean onTouchEvent(MotionEvent event) {
		//boolean b = super.onTouchEvent(event);
		super.onTouchEvent(event);
		if(event.getAction()==MotionEvent.ACTION_DOWN){
			setAlpha(0.5f);
			postInvalidate();
		}else{
			setAlpha(1f);
			postInvalidate();
		}
		return true;
	}

   这样运行起来,就一切正常了


总结一下以上的小例子:

  1. 当重写View.onTouchEvent时,应该调用super.onTouchEvent,如果不调用此方法,系统应有的系统事件都无法使用,例如click,longclick等。
  2. onTouchEvent的Down后,return false,事件将不再继续传递下去,即不传递给move、up等,事件传递也随之消失。
  3. onTouchEvent的Down后,return true,事件将继续传递给后续的事件,即move、up等。








你可能感兴趣的:(Android-事件传递篇,Android,精品,事件传递机制,自定义View,蒙版效果,自定义按下样式)