View 事件传递原理

2019-07-29  本文已影响0人  gczxbb

触屏是用户和手机交互的基础,手指触屏时产生一系列事件,控制视图改变,在树形视图中,事件从顶层向下传递。

树结构叶子视图事件传递

视图是树结构叶子节点,无子视图,不管是 ViewGroup 或 View 类型,调用基类View 类的 dispatchTouchEvent() 方法。

public boolean dispatchTouchEvent(MotionEvent event) {
    boolean result = false;
    ...
    final int actionMasked = event.getActionMasked();
    if (actionMasked == MotionEvent.ACTION_DOWN) {
        stopNestedScroll();
    }
    if (onFilterTouchEventForSecurity(event)) {
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnTouchListener != null
                && (mViewFlags & ENABLED_MASK) == ENABLED
                && li.mOnTouchListener.onTouch(this, event)) {
            result = true;
        }
        if (!result && onTouchEvent(event)) {
            result = true;
        }
    }
    if (actionMasked == MotionEvent.ACTION_UP ||
            actionMasked == MotionEvent.ACTION_CANCEL ||
            (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
        stopNestedScroll();
    }
    return result;
}

onTouchListener 监听器,优先级较高,调用 Touch 监听器的 onTouch() 方法,如果未消费,调用自己的 onTouchEvent() 方法。

注意,树结构最底部的叶子节点不一定是 View 类型,也可以是 ViewGroup 类型,一个ViewGroup类型叶子节点视图未消费事件,也会调用它的基类 View 的 dispatchTouchEvent() 方法,自己处理。

View 类的 onTouchEvent() 方法,当 viewFlags 支持 CLICKABLE,LONG_CLICKABLE 标志位,视图可点击,该方法会消费事件,且在 up 事件时, performClick() 方法触发点击监听,Button 控件支持 CLICKABLE 标志,TextView 控件不支持,触摸时不会消费事件。

可以重写子类 View 的 onTouchEvent() 方法,控制视图消费事件,也可以添加Touch监听器。

一个视图自身是否消费事件,由 onTouchListener 监听器和 View 的 onTouchEvent() 方法共同决定。


任重而道远

上一篇 下一篇

猜你喜欢

热点阅读