美文网首页基础知识Android自定义View
dispatchTouchEvent、onInterceptTo

dispatchTouchEvent、onInterceptTo

作者: 々志尚 | 来源:发表于2018-04-03 14:31 被阅读65次

简述

1.View对触摸事件的处理机制
2.ViewGroup对触摸事件的处理机制
3.android对触摸体系的概念
4.混合ViewGroup、View的分发拦截机制

1.View对触摸事件的处理机制

View中触摸事件方法有两个:dispatchTouchEvent、onTouchEvent
调用顺序为 :dispatchTouchEvent ——> onTouchEvent

public boolean dispatchTouchEvent(MotionEvent event) {

//省略......

    if (mInputEventConsistencyVerifier !=null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
    }

//省略......

if (!result && onTouchEvent(event)) {
result =true;
        }
}
//省略
......
return result;
}

2.ViewGroup对触摸事件的处理机制

ViewGrouop中触摸事件方法有三个dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
调用顺序为 :dispatchTouchEvent ——> onInterceptTouchEvent ——> onTouchEvent

// ViewGrouo源码分析
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1); }

// 省略
..........

if (actionMasked == MotionEvent.ACTION_DOWN ||mFirstTouchTarget !=null) {
final boolean disallowIntercept = (mGroupFlags &FLAG_DISALLOW_INTERCEPT) !=0;
if (!disallowIntercept) {  // 如果返回false
intercepted = onInterceptTouchEvent(ev); // 方法传递
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}

从源码可以看出来所有触摸事件的触发都是在 dispatchTouchEvent 方法开始的,如果对源码感兴趣的同学可以去看一下哦!

3.android对触摸体系的概念

在android中对触摸事件有两个概念:分发、拦截

注意:在UI中,对触摸事件的处理是从父类开始执行的,首先执行了父类的dispatchTouchEvent 才会去执行子类的 dispatchTouchEvent,遵循先父后子的原则

分发

分发可以理解为传递的意思,是触摸view之后所传递执行事件方法的一种机制: 
       view: dispatchTouchEvent 方法分发给 onTouchEvent 方法
       viewGroup :dispatchTouchEvent 方法分发 给onInterceptTouchEvent方法分发 给 onTouchEvent 方法

分发机制就是调用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的时候返回值为false

分发可以事件对本身的分发,也可以是向下View(ViewGroup)分发

拦截

拦截可以理解为对该事件停止向下View(ViewGroup)或本身传递触摸事件

拦截机制就是对调用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的时候返回值为true

拦截事件之后,就不再向下传递消息机制了

混合ViewGroup、View的分发拦截机制

举个例子说明一下。看图

分发拦截机制图

图中有四个View:View A、View B、View C、View D
其中View B和View D是view,View A和View C是ViewGroup

接下来我们对该试图进行触摸事件操作:

1、从 View A 视图开始操作:

我们对 A 试图进行操作,系统首先会调用 dispatchTouchEvent 方法,判断该返回值。如果是 true 则拦截事件,剩下的方法都不会被调用,如果是 false ,则会调用 onInterceptTouchEvent 方法判断返回值。如果是true,则会调用 A 中的 onTouchEvent 方法,如果是 false 则会判断被触摸发该区域是否有子view,发现没有,则同样会调用 A 的 onTouchEvent 方法。

2、从 View B 试图开始操作

我们对B试图进行操作,因为 B 的存在父试图 View A,所以首先android系统会先调用 A 的 dispatchTouchEvent 方法,在该方法进行判断返回值。如果返回 true,剩下的方法不会执行,返回 false,则会调用 A 的 onInterceptTouchEvent方法,判断返回值。如果为true,则调用 A 的 onTouchEvent 方法,如果为 false,则会调用 View B 的 dispatchTouchEvent  方法进行判断,如果返回true,剩下的方法不会调用,直接返回 View A中的  onTouchEvent 方法,如果返回false,因为View B 是 View ,没有 onInterceptTouchEvent  方法,所以直接会调用 onTouchEvent 方法,判断返回值。如果返回true,说明该事件已经被处理,如果返回false,则会调用 父View A 的 onTouchEvent  方法。

机制都是以false处理的

3、从 View C 视图开始操作

首先会调用 A 的 dispatchTouchEvent 方法,true剩下的方法不会调用,false调用 A 的 onInterceptTouchEvent 方法判断。true调用 A 的 onTouchEvent  方法,false 调用 C 的 dispatchTouchEvent 方法判断返回值。true返回 A 的 onTouchEvent  方法,false调用 C 的 onInterceptTouchEvent  方法判断。true返回 A 的 onTouchEvent  方法,false调用 C 的  onTouchEvent  方法判断。true调用 A 的onTouchEvent  ,false 先判断该视图是否有子View,有就分发机制给子view,没有就返回 A 的 onTouchEvent  方法。

机制都是以false处理的

4.从 View D 试图操作

首先执行 3 的操作到 View C试图分发机制到 View D 的 dispatchTouchEvent 方法,true就处理完事件处理返回 View C 的 onTouchEvent  方法再返回到 View A 的onTouchEvent  方法,false 就先返回到 View C  的onTouchEvent  方法再返回到 View A 的 onTouchEvent   方法。

机制都是以false处理的

有兴趣的同学可以试一下哦

源码

我说的不是很清晰,希望大神看到可以指正错误

相关文章

网友评论

    本文标题:dispatchTouchEvent、onInterceptTo

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