一、分发机制总结
1、传递顺序:Activity->PhoneWindow->DecorView->ViewGroup->View
2、三个方法:
* dispatchTouchEvent用来进行事件的分发。如果事件能够传递给当前的View,那么此方法一定会被调用,返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。
* onInterceptTouchEvent是用来判断是否拦截某个事件,如果当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。默认返回false,返回true表示拦截。Activity和View中不存在onInterceptTouchEvent方法。
* onTouchEvent在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前的事件,如果不消耗,则在同一个事件序列中,当前View无法再次接受到事件。view中默认返回true,表示消费了这个事件。
3、onTouch和onTouchEvent的区别:
这两个方法都是在View的dispatchTouchEvent中调用的,onTouch方法优先于onTouchEvent方法执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。
4、ViewGroup 是根据 onInterceptTouchEvent 的返回值来确定是调用子View的 dispatchTouchEvent 还是自身的 onTouchEvent
二、结论验证:
流程图:
3、点击View,ViewGroup将事件拦截
4、点击View,onTouchEvent返回true或者false。给view设置点击事件
findViewById(R.id.id_touch_view).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("TouchView", "onClick: " );
}
});
复制代码
结论:点击事件未执行,因为点击事件是在onTouchEvent方法的ACTION_UP中执行,返回true或者false,点击事件都执行不到
5、点击view,给view设置onTouchListener,并且返回true
findViewById(R.id.id_touch_view).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("TouchView", "onTouch: " );
return true;
}
});
复制代码