Android杂谈(12)View的事件分发机制

转载请注意:http://blog.csdn.net/wjzj000/article/details/52493877

本菜GitHub上开源了一个小的Android项目,感兴趣的看官大大们可以star下:

https://github.com/zhiaixinyang/MyFirstApp



今天记录一下View的事件分发机制。(增加了全新的补充)

其实关于这方面有很多书籍博客都在讲,看别人的终究是别人的思路和理解。有必要自己重新记录一下,用自己的思考梳理一个属于自己的富强、民主、文明、和谐,自由、平等、公正、法治、爱国、敬业、诚信、友善的社会主义核心价值观。

首先既然谈到分发,那就说明控件至少是嵌套的。像这样

我来略微的解释一下这样图片。OneViewGroup和TwoViewGroup是继承了一个LinearLayout,并重写了:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//把方法名翻译过来:发送触摸事件
    Log.d("AAAAAAA","OneViewGroup:dispatchTouchEvent");
    return super.dispatchTouchEvent(ev);
}

//ViewGroup中特有方法,方法翻译过来就是拦截触摸事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    Log.d("AAAAAAA","OneViewGroup:onInterceptTouchEvent");
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("AAAAAAA","OneViewGroup:onTouchEvent");
    return super.onTouchEvent(event);
}

OneView是继承一个TextView。重写了:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    Log.d("AAAAAAAAA","OneView:dispatchTouchEvent");
    return super.dispatchTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d("AAAAAAAAA","OneView:onTouchEvent");
    return super.onTouchEvent(event);
}
当我点击OneView时,Log的信息是这样的:

那么接下来就让我们梳理一下这个过程:
	首先是最下层的OneViewGroup中的dispatchTouchEvent()方法被调用。在OneViewGroup中紧接着调用onInterceptTouchEvent(),这个方法用于判断是否触发了
点击事件,也就是,是否调用自己的onTouchEvent()的方法。(很多地方称此为拦截事件,为啥我不这么说呢,因为我不喜欢这么说~)。如何判断是否调用,是通过
这个方法的返回值进行判断,如果这个方法返回true,那么OneViewGroup中的onTouchEvent()将会调用。返回false那么OneViewGroup中的事件处理到此结束,TwoViewGroup
将开始刚才OneViewGroup所进行的一系列过程....让我们把目光凝注在OneView中,过程还是如上述那样,但是我触摸了OneView,所以在OneView中的onInterceptTouchEvent()
中返回了true,onTouchEvent()被调用....OK,过程就是这样!

							
如果点击了OneViewGroup以及TwoViewGroup会怎么样呢?

点击TwoViewGroup后,TwoViewGroup中的onTouchEvet()被调用,这个事件被消费,所以OneView中的相关方法并没有被触发。


点击OneViewGroup后,效果同上....

但是如果我们仔细看,可以看到这几次的Log中好像有了问题,那就是在结束了onTouchEvent()后,
又重新走了一遍除了没有onInterceptTouchEvent()的方法的过程...
							
							我也不知道啊....
							
16年10月19日,补充:
当父级控件的onInterceptTouchEvent()重写并返回true,那么父级控件重写的onTouchEvent()会执行。
如果父级控件返回的为false,那么将执行子控件重写了onTouchEvent()。如果子控件没有重写onTouchEvent()
那么父级控件中的onTouchEvent()将被执行。
 这里有个值得注意的地方:
如果子控件即重写了onTouch,并且还重写了onClick。将会分情况执行:
	如果onTouch中返回false,那么当触摸此控件时,依次执行onTouch以及onClick。
	如果返回true,那么onClick将不会执行!其实也就是说,当onTouch中返回true说明事件到此彻底终止,
不在往下传递,也就是很多人说的事件被消费了。那么侧面我们也能得知,onClick是在onTouch之后被执行的。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值