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

2018-07-23  本文已影响101人  谢尔顿

下面是看完一步步探索学习Android Touch事件分发传递机制(一)这篇文章后,自己手动练习的总结。

1. 效果图

下面布局中用到的控件都是自定义的,我们可以通过对自定义控件的相关事件方法添加log。


练习图

2.主要代码

    @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);
    }
    @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);
    }
    @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);
    }
    @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事件。

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为例)

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时,会将事件传递给上一级View的onTouchEvent()方法处理。由于Activity已经没有比它更高一级的View,所以如果时Activity的dispatchTouchEvent方法return false的话,事件会直接被消费掉(即终止传递)。

(3)接着让dispatchTouchEvent方法return true(以ViewGroup2为例)

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时,事件会被消费掉不再传递

(4)让最里层View的OnTouchEvent()返回false

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时,跟默认return super是一样的,都会一直向上传递到上一级view的onTouchEvent()方法。

(5)让最里层View的onTouchEvent()方法返回true

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时,事件会被消费掉,不在传递,跟dispatchTouchEvent返回true的时候类似。

(6)让ViewGroup2的onInterceptTouchEvent()返回false

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()方法return false和return super是一样的,都是默认将触摸事件传递给下一级view的dispatchTouchEvent方法。

(6)让ViewGroup2的onInterceptTouchEvent()返回true

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时,Touch事件才会被直接传递给ViewGoup自己的onTouchEvent方法处理。

4.最后的总结

(1)对应dispatchTouchEvent()方法

(2)对应onTouchEvent()方法

(3)对应onInterceptTouchEvent()方法

值得学习的文章:

上一篇下一篇

猜你喜欢

热点阅读