自定义控件之触摸事件的传递

层面优先级:Activity-->ViewGroup-->View

1、dispatchTouchEvent方法:

每个View包括ViewGroup中都能重写此方法,该方法是用来分发触摸事件的。是一个布局中,触摸事件首先执行的的方法。如果dispatchTouchEvent返回值是true,代表触摸事件分发给本View的onTouchEvent。如果返回值是false,那么触摸事件分发给本View的onInterceptEvent(如果是View,就没有该方法,那么事件就到此终止了)。

一般情况下,不建议重写该方法。


2、Demo介绍,MyLinearLayout继承了LinearLayout,MyTextView继承了TextView,布局如下图


MyLinearLayout中,重写了onInterceptTouchEvent和onTouchEvent(dispatchTouchEvent没有重写,这个比较容易理解,分析在第一点)。MyTextView中,重写了onTouchEvent方法(View中没有onInterceptTouchEvent)。


(1)情况一,MyLinearLayout里的onInterceptTouchEvent返回默认值(false),MyTextView的onTouchEvent返回true。

触摸上面的MyTextView部分,结果如下


结论,onInterceptTouchEvent返回false的意思是把触摸事件往下传递给其子View(实际上先抵达子View的dispatchTouchEvent方法,默认返回true),所以即是传递给MyTextView的onTouchEvent方法。首先是down从MyLinearLayout的onInterceptTouchEvent传递到MyTextView的onTouchEvent,发现onTouchEvent的返回值是true,意思就是说自己消费此触摸事件,不会往其父MyLinearLayout的onTouchEvent传递了。那么接下来move和up都是按上面的形式传递。


(2)情况二,MyLinearLayout里的onInterceptTouchEvent返回默认值(false),MyTextView的onTouchEvent返回默认值(false),MyLinearLayout里的onTouchEvent返回true。触摸上面的MyTextView部分,结果如下。


结论,MyLinearLayout的onInterceptTouchEvent返回false,down事件往下传递到MyTextView的onTouchEvent,由于此时false,没有办法自己消费此事件,那么就往其父MyLinearLayout的onTouchEvent里传递了,此时MyLinearLayout的onTouchEvent返回true,代表要自己消费此触摸事件,所以不会再继续往上传了。注意了,后面的move和up会继续触发,不过不会再分发给MyLinearLayout的onInterceptTouchEvent了(所以也不可能到MyTextView的onTouchEvent),而是直接到MyLinearLayout的onTouchEvent。(只要onTouchEvent返回true,up事件必然是在这里完成的)。


(3)情况三,MyLinearLayout里的onInterceptTouchEvent返回默认值(false),MyTextView的onTouchEvent返回默认值(false),MyLinearLayout里的onTouchEvent返回false。触摸上面的MyTextView部分,结果如下。

结论,与情况二的区别在于MyLinearLayout的onTouchEvent返回false。down事件传到MyLinearLayout的onTouchEvent,返回值是false,然后再往其父的onTouchEvent传,其后的move和up事件都被onTouchEvent返回值是true的某个父类消费了,类似于情况二,中间的不会传递到。


(4)情况四,MyLinearLayout里的onInterceptTouchEvent返回true,MyLinearLayout里的onTouchEvent返回true。
触摸上面的MyTextView部分,结果如下。


结论,MyLinearLayout的onInterceptTouchEvent返回true,触摸事件不往子View里传了,而是传给自己的onTouchEvent。down事件过来后,返回值是true,那么就说明了它自己消费了此次的触摸事件,所以MyLinearLayout的dispatchTouchEvent分发的时候就不再往onInterceptTouchEvent分发了,所以后面的move和up都是直接传到本View的onTouchEvent。


(5)情况五,MyLinearLayout里的onInterceptTouchEvent返回true,MyLinearLayout里的onTouchEvent返回false。

触摸上面的MyTextView部分,结果如下。


情况五就是情况三和情况四的结合。


--------------------------------------------------以下部分是触摸MyLinearLayout-------------------------------------------------------------

(6)情况六,MyLinearLayout的onInterceptTouchEvent返回false,MyLinearLayout里的onTouchEvent返回true

结果如下:


结论,onInterceptTouchEvent无论返回true还是false,结果都是和上面一致。返回false就是给子View的onTouchEvent,由于没有对MyTextView触摸,所以此时的子View可以理解为没有,那就是本身。而返回true就是传递给本View的onTouchEvent。onTouchEvent返回值是true在前面已经分析过了。


(7)情况七,MyLinearLayout的onInterceptTouchEvent返回false,MyLinearLayout里的onTouchEvent返回false

结果如下:


结论,onInterceptTouchEvent无论返回true还是false,结果都是和上面一致。分析如情况六。onTouchEvent返回值是false在前面已经分析过了。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值