下面是看完一步步探索学习Android Touch事件分发传递机制(一)这篇文章后,自己手动练习的总结。
1. 效果图
下面布局中用到的控件都是自定义的,我们可以通过对自定义控件的相关事件方法添加log。
练习图
2.主要代码
- Activity
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG,"Activity's onTouchEvent returns super");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i(TAG,"Activity's dispatchTouchEvent returns super");
return super.dispatchTouchEvent(ev);
}
- ViewGroup1
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG,"ViewGroup1's onTouchEvent returns super");
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i(TAG,"ViewGroup1's onInterceptTouchEvent returns super");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i(TAG,"ViewGroup1's dispatchTouchEvent returns super");
return super.dispatchTouchEvent(ev);
}
- ViewGroup2
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG,"ViewGroup2's onTouchEvent returns super");
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i(TAG,"ViewGroup2's onInterceptTouchEvent returns super");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i(TAG,"ViewGroup2's dispatchTouchEvent returns super");
return super.dispatchTouchEvent(ev);
}
- View
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG,"View's onTouchEvent returns super");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i(TAG,"View's dispatchTouchEvent returns super");
return super.dispatchTouchEvent(ev);
}
3. log的打印
(1)默认情况下所有方法都是return super(即父类的默认实现方法),所以我们接下来看看一个ACTION_DOWN事件是怎么传递的。我们给最里面的view一个触摸,产生ACTION_DOWN事件。
- log
3 10:51:24.339 12065-12065/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 10:51:24.341 12065-12065/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 10:51:24.341 12065-12065/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 10:51:24.341 12065-12065/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns super
07-23 10:51:24.342 12065-12065/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onInterceptTouchEvent returns super
07-23 10:51:24.342 12065-12065/com.gjj.androidstudydemo I/TextView1: View's dispatchTouchEvent returns super
07-23 10:51:24.342 12065-12065/com.gjj.androidstudydemo I/TextView1: View's onTouchEvent returns super
07-23 10:51:24.342 12065-12065/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onTouchEvent returns super
07-23 10:51:24.342 12065-12065/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onTouchEvent returns super
07-23 10:51:24.343 12065-12065/com.gjj.androidstudydemo I/EventStudyActivity: Activity's onTouchEvent returns super
-
对应的流程图:
默认的事件分发
(2)接下来将我们探索dispatchTouchEvent方法,令其return false(以ViewGroup2为例)
- log
07-23 11:51:04.761 13547-13547/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 11:51:04.764 13547-13547/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 11:51:04.765 13547-13547/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 11:51:04.765 13547-13547/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns false
07-23 11:51:04.765 13547-13547/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onTouchEvent returns super
07-23 11:51:04.766 13547-13547/com.gjj.androidstudydemo I/EventStudyActivity: Activity's onTouchEvent returns super
-
对应的流程图
dispatchTouchEvent返回false时
结论:当dispatchTouchEvent()返回false时,会将事件传递给上一级View的onTouchEvent()方法处理。由于Activity已经没有比它更高一级的View,所以如果时Activity的dispatchTouchEvent方法return false的话,事件会直接被消费掉(即终止传递)。
(3)接着让dispatchTouchEvent方法return true(以ViewGroup2为例)
- log
07-23 13:09:59.340 16258-16258/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 13:09:59.343 16258-16258/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 13:09:59.343 16258-16258/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 13:09:59.343 16258-16258/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns true
-
对应的流程图
dispatchTouchEvent()返回true时
总结:如果dispatchTouchEvent()返回true时,事件会被消费掉不再传递
(4)让最里层View的OnTouchEvent()返回false
- log
07-23 13:23:00.634 17096-17096/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 13:23:00.636 17096-17096/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 13:23:00.636 17096-17096/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 13:23:00.637 17096-17096/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns super
07-23 13:23:00.637 17096-17096/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onInterceptTouchEvent returns super
07-23 13:23:00.637 17096-17096/com.gjj.androidstudydemo I/TextView1: View's dispatchTouchEvent returns super
07-23 13:23:00.637 17096-17096/com.gjj.androidstudydemo I/TextView1: View's onTouchEvent returns false
07-23 13:23:00.637 17096-17096/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onTouchEvent returns super
07-23 13:23:00.638 17096-17096/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onTouchEvent returns super
07-23 13:23:00.639 17096-17096/com.gjj.androidstudydemo I/EventStudyActivity: Activity's onTouchEvent returns super
-
对应的流程图
onTouchEvent返回false
总结:如果onTouchEvent()方法返回false时,跟默认return super是一样的,都会一直向上传递到上一级view的onTouchEvent()方法。
(5)让最里层View的onTouchEvent()方法返回true
- log
07-23 13:33:38.305 17383-17383/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 13:33:38.309 17383-17383/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 13:33:38.309 17383-17383/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 13:33:38.309 17383-17383/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns super
07-23 13:33:38.310 17383-17383/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onInterceptTouchEvent returns super
07-23 13:33:38.310 17383-17383/com.gjj.androidstudydemo I/TextView1: View's dispatchTouchEvent returns super
07-23 13:33:38.310 17383-17383/com.gjj.androidstudydemo I/TextView1: View's onTouchEvent returns true
-
对应的流程图
onTouchEvent()方法返回true
总结:如果onTouchEvent()方法返回true时,事件会被消费掉,不在传递,跟dispatchTouchEvent返回true的时候类似。
(6)让ViewGroup2的onInterceptTouchEvent()返回false
- log
07-23 13:47:03.714 17867-17867/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 13:47:03.718 17867-17867/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 13:47:03.718 17867-17867/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 13:47:03.719 17867-17867/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns super
07-23 13:47:03.719 17867-17867/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onInterceptTouchEvent returns false
07-23 13:47:03.719 17867-17867/com.gjj.androidstudydemo I/TextView1: View's dispatchTouchEvent returns super
07-23 13:47:03.719 17867-17867/com.gjj.androidstudydemo I/TextView1: View's onTouchEvent returns super
07-23 13:47:03.719 17867-17867/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onTouchEvent returns super
07-23 13:47:03.720 17867-17867/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onTouchEvent returns super
07-23 13:47:03.721 17867-17867/com.gjj.androidstudydemo I/EventStudyActivity: Activity's onTouchEvent returns super
-
对应的流程图
onInterceptTouchEvent返回false
总结:通过流程图我们可以发现onInterceptTouchEvent()方法return false和return super是一样的,都是默认将触摸事件传递给下一级view的dispatchTouchEvent方法。
(6)让ViewGroup2的onInterceptTouchEvent()返回true
- log
07-23 13:56:07.528 18165-18165/com.gjj.androidstudydemo I/EventStudyActivity: Activity's dispatchTouchEvent returns super
07-23 13:56:07.530 18165-18165/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's dispatchTouchEvent returns super
07-23 13:56:07.531 18165-18165/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onInterceptTouchEvent returns super
07-23 13:56:07.531 18165-18165/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's dispatchTouchEvent returns super
07-23 13:56:07.531 18165-18165/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onInterceptTouchEvent returns true
07-23 13:56:07.531 18165-18165/com.gjj.androidstudydemo I/ViewGroup2: ViewGroup2's onTouchEvent returns super
07-23 13:56:07.531 18165-18165/com.gjj.androidstudydemo I/ViewGroup1: ViewGroup1's onTouchEvent returns super
07-23 13:56:07.532 18165-18165/com.gjj.androidstudydemo I/EventStudyActivity: Activity's onTouchEvent returns super
-
对应的流程图
onInterceptTouchEvent()返回true
总结:如果onInterceptTouchEvent()方法返回true时,Touch事件才会被直接传递给ViewGoup自己的onTouchEvent方法处理。
4.最后的总结
(1)对应dispatchTouchEvent()方法
- return true:消费掉事件,终止传递。
- return false:将事件传递给上一级view的onTouchEvent方法,如果是Activity的dispatchTouchEvent方法,则也是消费掉事件,终止传递。
- return super:如果是Activity,则传递给下一级view的dispatchTouchEvent;如果是ViewGroup,则传递给自己的onInterceptTouchEvent;如果是View,则传递给自己的onTouchEvent()。
(2)对应onTouchEvent()方法
- return true:消费掉事件,终止传递。
- return false/super:将事件传递给上一级view的onTouchEvent方法。
(3)对应onInterceptTouchEvent()方法
- return true:将事件传递给ViewGroup自己的onTouchEvent方法处理。
- return false/super:将事件传递给下一级View的dispatchTouchEvent()。
值得学习的文章:
网友评论