触屏是用户和手机交互的基础,手指触屏时产生一系列事件,控制视图改变,在树形视图中,事件从顶层向下传递。
树结构叶子视图事件传递
视图是树结构叶子节点,无子视图,不管是 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() 方法共同决定。
任重而道远
网友评论