美文网首页
Android事件分发机制--->ACTION_DOWN事

Android事件分发机制--->ACTION_DOWN事

作者: 谢尔顿 | 来源:发表于2018-07-23 14:26 被阅读101次

    下面是看完一步步探索学习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()。

    值得学习的文章:

    相关文章

      网友评论

          本文标题:Android事件分发机制--->ACTION_DOWN事

          本文链接:https://www.haomeiwen.com/subject/ypidmftx.html