美文网首页
View的事件分发机制(上)

View的事件分发机制(上)

作者: FourStars | 来源:发表于2018-10-23 23:17 被阅读0次

在我们使用手机的时候,会与应用进行各种交互行为,每次滑动,点击都是一种触摸事件,在Android中有如下一些触摸事件

  • ACTION_DOWN = 0,手触摸到屏幕时触发
  • ACTION_UP = 1,手按完屏幕,离开屏幕时出发
  • ACTION_MOVE = 2,手在屏幕上滑动时触发
  • ACTION_CANCEL =3,接收到触摸事件中任一事件后,其后续的事件被拦截无法接收,则触发cancel
  • ACTION_OUTSIDE = 4,手滑到屏幕外或者View之外,一般不由该View进行处理,而是通过Window.Callback进行回调

如何分发触摸事件

image.png

大致分发流程
Activity收到事件,并传给小弟处理(DecorView也是一个ViewGroup)

Activity -> PhoneWindow -> ViewGroup -> ... -> View

若小弟处理不了,则回传给Activity

Activity <- PhoneWindow <- ViewGroup <- ... <- View

对于事件,Android中有三个方法来处理它

  • dispatchTouchEvent() -- 分发事件,将事件传递出去
  • onInterceptTouchEvent() -- 拦截事件,子View或下一层级的就收不到该事件
  • onTouchEvent() -- 处理事件

Activity,ViewGroup,View中是否含有上述方法

方法 Activty ViewGroup View
dispatchTouchEvent()
onInterceptTouchEvent() × ×
onTouchEvent()

由上表可见,Activity和View都没有拦截事件的方法
因为Activiy处于事件分发的顶端,若拦截了,View就无法做出响应,影响用户体验
而View处于最底层,再拦截事件已经没有意义,要么就处理掉事件,要么就不做处理

分发流程的比喻

  • Activity:老板
  • RootView:经理
  • ChildView:员工

在方法中进行打印log,默认调用父类方法(即返回值均为false),布局如下

image.png

Tips:操作方式为点击ChildView,只有Down,没有Up的行为,模拟器上鼠标按住即可

dispatchTouchEvent: ---------ViewActivity--老板:接到活啦
dispatchTouchEvent: ---------RootView-----经理:我也接到活啦
onInterceptTouchEvent: -----RootView-----经理:偷懒,丢给员工做
dispatchTouchEvent: ---------ChildView----员工:狗经理又来压榨我了,收到任务
onTouchEvent: -----------------ChildView----员工:发现做不了,告知经理
onTouchEvent: -----------------RootView----经理:报告老板,做不了啊!
onTouchEvent: -----------------ViewActivity-老板:报告客户,这活我不做了

ChildView中onTouchEvent为true时,即员工发现这个活自己能做,则经理和老板就不用处理啦

dispatchTouchEvent: ---------ViewActivity
dispatchTouchEvent: ---------RootView
onInterceptTouchEvent: -----RootView
dispatchTouchEvent: ---------ChildView
onTouchEvent: -----------------ChildView

RootView中onInterceptTouchEvent为true时,经理有B数,知道员工做不了,就不告知员工了,此时员工不需要处理,只要经理上报回老板即可

dispatchTouchEvent: -------ViewActivity
dispatchTouchEvent: -------RootView
onInterceptTouchEvent: ---RootView
onTouchEvent: ---------------RootView
onTouchEvent: ---------------ViewActivity

总结

对于 dispatchTouchEvent

  • Activity
    • ture:事件被消耗,不会传递给经理,就是不理会客户的活
    • false:接活,并传下去让下一层处理
  • ViewGroup(RootView)
    • 情况跟Activity类似,要么不做,要么传给小弟
  • View
    • true:回调onTouchEvent()
    • false:不回调

简而言之就是true时会回调onTouchEvent(),false则不回调

对于 onInterceptTouchEvent
拦截后(返回值为true),下一层不会回调dispatchTouchEvent(),而是自己处理,更不会回调下一层的onTouchEvent()

对于 onTouchEvent
false的话就会告知上层,让上层进行处理
而true的话,自己做完后就行,不必汇报上层

参考(copy)

安卓自定义View进阶-事件分发机制原理

相关文章

网友评论

      本文标题:View的事件分发机制(上)

      本文链接:https://www.haomeiwen.com/subject/fncnzftx.html