让我来详细讲解一下“Android Touch事件分发过程详解”的完整攻略。
一、Touch事件分发的概念及过程
在Android开发中,Touch事件是非常重要的一种事件类型。而Touch事件的分发过程也是我们需要了解的重要知识之一。Touch事件分发的过程可以简单地分为三个步骤:从根View开始往下递归地遍历View树,找到最合适的View来处理事件。
1. 步骤一:Touch事件的传递
当Touch事件发生时,它会被传递到当前界面的最外层View,即DecorView,然后再由DecorView传递到Activity的ContentView,再由ContentView传递到子View,一直往下传递,直到最后的目标View。
2. 步骤二:事件的分发
事件分发的过程是从外到内依次触发了三个方法:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。
2.1 dispatchTouchEvent方法
ViewGroup会重写dispatchTouchEvent方法,同时它也是Touch事件的入口方法,它用来协调Touch事件的分发。在dispatchTouchEvent方法中,ViewGroup会调用onInterceptTouchEvent方法来判断是否拦截Touch事件。
2.2 onInterceptTouchEvent方法
在触发onInterceptTouchEvent方法时,会传入MotionEvent参数,即Touch事件。当ViewGroup的onInterceptTouchEvent方法返回true时,表示Touch事件被它拦截了,就不会再往下传递并进入View的onTouchEvent方法。如果返回false,则会继续往下传递。
2.3 onTouchEvent方法
当Touch事件被确定分发到某个View上时,该View会触发onTouchEvent方法来消费Touch事件。该方法的返回值为boolean类型,如果返回true,则表示该View消费了Touch事件,不再往下传递。如果返回false,则表示该View不消费Touch事件,会将Touch事件传递给它的父View,直到被某个View消费为止。
3. 步骤三:事件的处理
当Touch事件被一个View消费时,它就会被处理。View会根据Touch事件的类型,调用相应的方法来处理该事件,比如对于OnClickListener事件,可以通过调用View.performClick()方法来处理。
二、示例说明
为了更好地理解Touch事件分发的过程,下面来模拟两个场景,分别为ViewGroup和View的事件分发场景:
1. ViewGroup的事件分发
在一个LinearLayout中放置了4个Button。为了模拟事件分发过程,我们对LinearLayout和Button都重写了dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent方法。代码如下:
public class MyLinearLayout extends LinearLayout {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("MyLinearLayout", "dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("MyLinearLayout", "onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i("MyLinearLayout", "onTouchEvent");
return super.onTouchEvent(event);
}
}
public class MyButton extends Button {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("MyButton", "dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i("MyButton", "onTouchEvent");
return super.onTouchEvent(event);
}
}
当我们点击Button时,输出的日志如下:
MyLinearLayout: dispatchTouchEvent
MyLinearLayout: onInterceptTouchEvent
MyButton: dispatchTouchEvent
MyButton: onTouchEvent
MyButton: dispatchTouchEvent
MyButton: onTouchEvent
MyLinearLayout: onTouchEvent
从日志中可以看到,Touch事件首先被传递到了MyLinearLayout中,然后MyLinearLayout在onInterceptTouchEvent方法中将该事件拦截并消费,最终Touch事件在MyLinearLayout中被处理掉了。
2. View的事件分发
在一个TextView中,我们注册了一个OnTouchListener。代码如下:
textView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("MyTextView", "onTouch");
return false;
}
});
当我们点击TextView时,输出的日志如下:
MyTextView: onTouch
从日志中可以看到,由于TextView并没有重写dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent方法,因此Touch事件并不会在TextView中被分发处理。同时,由于OnTouchListener的返回值为false,表示未处理Touch事件,该Touch事件会继续往下传递并最终被父View处理。最终,Touch事件在View中被处理掉了。
总结
通过这两个示例,我们可以更好地理解Touch事件分发的过程及机制。对于开发中遇到的Touch事件相关问题,我们可以更加快速、准确地排查问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android Touch事件分发过程详解 - Python技术站