View中存在dispatchTouchEvent、onTouchEvent两个方法。

而ViewGroup中则存在dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三个方法。

调用顺序依次为dispatchTouchEvent——》onInterceptTouchEvent——》onTouchEvent

在Android的View层级触摸体系中,有两个重要的概念,分别是:分发和拦截


分发

分发可以理解为传递,是触摸消息的一种传播。

dispatchTouchEvent方法表示分发一个触摸消息,该方法返回boolean型参数,当返回true时则表示不再向下传递和分发该消息,后续的方法都不会被调用,返回false则表示该消息继续传递和分发。

当手机触摸屏被触摸的时候,父View的dispatchTouchEvent方法会最先被调用,如果返回false,则会调用该父View的onInterceptTouchEvent方法,并传递给子View,如果返回true,则会停止该父View和其子View的一切触摸方法。(也就是不处理这个触摸消息、常常面试会被问,如何禁止一个界面的所有触摸点击事件,则可以回答在该界面的rootview中实现dispatchTouchEvent并返回true)。


拦截

拦截可以理解为是否在该View中处理该触摸事件。

onInterceptEventTouch方法表示是否拦截该触摸事件,该方法返回boolean型参数,true表示拦截,false表示不拦截。当手机触摸屏被触摸时,父控件dispatchTouchEvent方法会通过判断返回值来决定是否调用拦截方法,当决定调用的时候,父View的onInterceptEventTouch方法会被调用,如果返回true,则会直接调用该View的onTouchEvent方法,并直接调用该父View的onTouchEvent方法,如果返回false,则会向子View传递该消息,在子View中继续则判断dispatchTouchEvent方法,重复上面分发的逻辑。


举个例子来说明这些。如图所示,是一个典型的界面层。


其中View A是父View,是个View Group,View B、View D是A的子View,其中View B也是个View Group,View D是个View,View C是B的子View,是个View。

我们都知道,再Android中,View是以树的形式存在的,所以我们还可以表现为如下形式


根是A,它的子节点有B、D,B有子节点为C。


假设①:我们如果触摸View A,android系统则会调用A的dispatchTouchEvent方法,该方法会判断返回值,如果为true,则止于该方法,剩下的都不会被调用,如果返回false,则会调用A的onInterceptTouchEvent方法并判断返回值,如果返回true,则调用A的onTouchEvent方法,如果返回false,则会判断该区域是否有其他子view,发现没有,则同样也调用A 的onTouchEvent方法。


假设②:我们触摸View D,android系统则会调用A的dispatchTouchEvent方法,该方法会判断返回值,如果为true,则止于该方法,剩下的都不会被调用,如果返回false,则会调用A的onInterceptTouchEvent方法并判断返回值,如果返回true,则调用A的onTouchEvent方法,如果返回false,则因为该区域还有子节点View D,则会调用D的dispatchTouchEvent方法并进行判断,如果是false,因为D是View,所以不会有onInterceptTouchEvent方法的判断,会调用D的onTouchEvent方法,如果D的onTouchEvent方法返回true,则说明在D上被处理该触摸事件,如果返回false,则会继续传递回D的父View也就是A,然后调用A的onTouchEvent方法,如果D的dispatchTouchEvent返回true,说明该消息不再分发,则不会调用D的剩下的方法,直接找D的父View也就是A,调用他的onTouch方法。


假设③:我们触摸View B,android系统则会调用A的dispatchTouchEvent方法,该方法会判断返回值,如果为true,则止于该方法,剩下的都不会被调用,如果返回false,则会调用A的onInterceptTouchEvent方法并判断返回值,如果返回true,则调用A的onTouchEvent方法,如果返回false,则因为该区域还有子节点View B,则会调用B的dispatchTouchEvent方法并进行判断,如果是false,因为B是ViewGroup,所以会调用B的onInterceptTouchEvent方法的判断,这时因为B是最后一个被触摸的子节点,所以不管是否返回true或者false,B都会拦截该触摸消息,调用B的onTouch,如果B的onTouch返回true,则结束,如果返回false则调用B的父节点A的onTouch。


假设④:我们触摸View C,android系统则会调用A的dispatchTouchEvent方法,该方法会判断返回值,如果为true,则止于该方法,剩下的都不会被调用,如果返回false,则会调用A的onInterceptTouchEvent方法并判断返回值,如果返回true,则调用A的onTouchEvent方法,如果返回false,则因为该区域还有子节点View B,则会调用B的dispatchTouchEvent方法并进行判断,如果是false,因为B是ViewGroup,所以会调用B的onInterceptTouchEvent方法的判断,这时如果返回true,则拦截该方法,调用B的onTouch方法,如果B的onTouch返回true,则止于此,如果返回false,则调用B的父节点A的onTouch,如果B的onInterceptTouchEvent返回false,则继续调用B的子节点C的dispatchTouchEvent方法,并执行上面说的那些操作。。。


说起来很绕口,但这个例子可以帮助你理解这个触摸逻辑。

更多相关文章

  1. [Android问答] 如何获得手机屏幕分辨率?
  2. Android平台开发-Power management-电源管理
  3. 【Android(安卓)开发教程】屏幕方向的改变
  4. 获取android顶部状态栏高度的两种方式
  5. Android(安卓)ColorStateList使用方法
  6. Android(安卓)中文 API (101) —— AsyncTask
  7. Android(安卓)ColorStateList使用方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android(安卓)WebView中的JavaScript调用
  2. Android(安卓)控件的显示和隐藏
  3. Android(安卓)轮询实现的三种方式
  4. 切换选项卡
  5. Android系统属性SystemProperties.set/ge
  6. 编译V8静态库 for Android
  7. android开源工程
  8. Android(安卓)Ble
  9. adb connect 失败时(unable to connect t
  10. Android(安卓)从网页中跳转到APP