事件分发测试及总结

来源:互联网 发布:java基础面试题及答案 编辑:程序博客网 时间:2024/06/05 03:12

最近在研究事件分发,看了书中的结论和源码解析,但是总想自己测试下看下结果,代码是
从鸿洋神博客中copy的,自己做了多种情况的测试。
事件分发测试:
分别自定义MyButton和MyLinearlayout两个类:
----------------------自定义MyButton类-------------

public class MyButton extends Button {    private static final String TAG = "MyButton";    public MyButton(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN:                Log.e(TAG, "onTouchEvent ACTION_DOWN");                break;            case MotionEvent.ACTION_MOVE:                Log.e(TAG, "onTouchEvent ACTION_MOVE");                break;            case MotionEvent.ACTION_UP:                Log.e(TAG, "onTouchEvent ACTION_UP");                break;            default:                break;        }        return super.onTouchEvent(event);    }    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        int action = event.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN:                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");                break;            case MotionEvent.ACTION_MOVE:                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");                break;            case MotionEvent.ACTION_UP:                Log.e(TAG, "dispatchTouchEvent ACTION_UP");                break;            default:                break;        }        return super.dispatchTouchEvent(event);    }}

----------------------自定义MyLinearlayout类----------

public class MyLinearlayout extends LinearLayout {    private static final String TAG = MyLinearlayout.class.getSimpleName();    public MyLinearlayout(Context context, AttributeSet attrs)    {        super(context, attrs);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev)    {        int action = ev.getAction();        switch (action)        {            case MotionEvent.ACTION_DOWN:                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");                break;            case MotionEvent.ACTION_MOVE:                Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");                break;            case MotionEvent.ACTION_UP:                Log.e(TAG, "dispatchTouchEvent ACTION_UP");                break;            default:                break;        }        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event)    {        int action = event.getAction();        switch (action)        {            case MotionEvent.ACTION_DOWN:                Log.e(TAG, "onTouchEvent ACTION_DOWN");                break;            case MotionEvent.ACTION_MOVE:                Log.e(TAG, "onTouchEvent ACTION_MOVE");                break;            case MotionEvent.ACTION_UP:                Log.e(TAG, "onTouchEvent ACTION_UP");                break;            default:                break;        }        return super.onTouchEvent(event);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev)    {        int action = ev.getAction();        switch (action)        {            case MotionEvent.ACTION_DOWN:                Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");                break;            case MotionEvent.ACTION_MOVE:                Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");                break;            case MotionEvent.ACTION_UP:                Log.e(TAG, "onInterceptTouchEvent ACTION_UP");                break;            default:                break;        }        return super.onInterceptTouchEvent(ev);    }    @Override    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept)    {        Log.e(TAG, "requestDisallowInterceptTouchEvent ");        super.requestDisallowInterceptTouchEvent(disallowIntercept);    }}

---------布局部分代码:布局中MyButton是MyLinearlayout的子控件--------

<com.testproject.CustomWidgets.MyLinearlayout                android:id="@+id/my_ll"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_gravity="center_horizontal"                android:gravity="center"                android:layout_marginTop="18dip">                <com.testproject.CustomWidgets.MyButton                    android:id="@+id/id_btn"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="click me" />            </com.testproject.CustomWidgets.MyLinearlayout>

----------------分类测试及结果:--------------------
首先,看下默认情况下的测试结果,可以分别作对比,默认分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouch ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouch ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
1.在MyButton的dispatchTouchEvent接受到ACTION_DOWN事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onTouchEvent ACTION_DOWN
总结:目标控件不接受ACTION_DOWN事件,那么同一个事件序列的后续事件都不会再传过来,最终这组事件会被Activity消耗
2.在MyButton的dispatchTouchEvent接受到ACTION_MOVE事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouch ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
总结:目标控件只要接受了ACTION_DOWN事件,那么同一个事件序列的后续事件都会传过来,不管目标控件是否处理这个事件也不管是如何处理,最终这些消失的点击事件会传递给Activity处理
3.在MyButton的dispatchTouchEvent接受到ACTION_UP事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouch ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
总结:同上
4.在MyButton的onTouchEvent接受到ACTION_DOWN事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ onTouchEvent ACTION_DOWN
总结:目标控件不处理ACTION_DOWN事件,那么同一个事件序列的后续事件都不会传过来,并且父控件的onTouchEvent会被调用
5.在MyButton的onTouchEvent接受到ACTION_MOVE事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouch ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouch ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
总结:目标控件只要处理了ACTION_DOWN事件,那么同一个事件序列的后续事件都会传过来,不管目标控件是否处理这个事件也不管是如何处理,并且不会再去调用父控件的onTouchEvent
6.在MyButton的onTouchEvent接受到ACTION_UP事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouch ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouch ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
总结:同上
---------------上面是通过MyButton这个子控件的处理测试,下面用MyLinearlayout做处理测试下加深理解-------------
1.在MyLinearlayout的dispatchTouchEvent接受到ACTION_DOWN事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
总结:不接受ACTION_DOWN事件,就不会再接收到同一序列事件
2.在MyLinearlayout的dispatchTouchEvent接受到ACTION_MOVE事件的时候返回false,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouch ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
总结:只要接受了ACTION_DOWN事件,就会接收到同一序列全部事件
---------------MyLinearlayout的onInterceptTouchEvent方法默认都是不会拦截事件的,事件不会传递给MyLinearlayout的onTouchEvent,所以不需要在MyLinearlayout的onTouchEvent做测试处理,接下来我们需要对MyLinearlayout的onInterceptTouchEvent方法做测试处理----------
1.在MyLinearlayout的onInterceptTouchEvent接受到ACTION_DOWN事件的时候返回true,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyLinearlayout﹕ onTouchEvent ACTION_DOWN
总结:父控件如果拦截了ACTION_DOWN事件,那么不会再向下传递这组事件,而是会调用自身的onTouchEvent去处理这一个序列的事件。由于这个序列的事件都直接传递给onTouchEvent处理,所以onTouchEvent本身返回true或false都没关系,不关心onTouchEvent内部是怎么处理的。
2.在MyLinearlayout的onInterceptTouchEvent接受到ACTION_MOVE事件的时候返回true,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onTouchEvent ACTION_UP
总结:只要父控件处理了ACTION_DOWN,那么同一序列的事件都需要通过onInterceptTouchEvent判断是否拦截,但是同一序列事件中是可能有多个ACTION_MOVE事件的,
这个多个ACTION_MOVE事件只有第一个会被拦截。等于说只能在onInterceptTouchEvent的ACTION_MOVE事件时候进行拦截并不起作用。
3.在MyLinearlayout的onInterceptTouchEvent接受到ACTION_UP事件的时候返回true,分发结果如下:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouch ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouch ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
总结:这种情况只有ACTION_UP事件被拦截
——————————–补充测试:ouTouch方法对事件的影响———————————–
1.在MyButton的setOnTouchListener的onTouch方法中返回true:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
2.在MyButton的setOnTouchListener的onTouch方法中返回false:
MyLinearlayout﹕ dispatchTouchEvent ACTION_DOWN
MyLinearlayout﹕ onInterceptTouchEvent ACTION_DOWN
MyButton﹕ dispatchTouchEvent ACTION_DOWN
MyButton﹕ onTouchEvent ACTION_DOWN
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_MOVE
MyLinearlayout﹕ onInterceptTouchEvent ACTION_MOVE
MyButton﹕ dispatchTouchEvent ACTION_MOVE
MyButton﹕ onTouchEvent ACTION_MOVE
MyLinearlayout﹕ dispatchTouchEvent ACTION_UP
MyLinearlayout﹕ onInterceptTouchEvent ACTION_UP
MyButton﹕ dispatchTouchEvent ACTION_UP
MyButton﹕ onTouchEvent ACTION_UP
总结:从上面两种情况可以得知,ouTouch方法返回true或者false唯一的区别就是MyButton的onTouchEvent会不会
接受并处理事件,但是并不影响整个事件序列的传递。因为在View中只有在dispatchTouchEvent和onTouchEvent接
受到down事件的时候可以返回false导致不再接受同一序列的后续事件;在ViewGroup中的dispatchTouchEvent接受
到down事件的时候返回false导致后续事件不接受,且在onInterceptRouchEvent接受到down事件时候返回true的时
候就会把这次事件直接给ViewGroup的onTouchEvent处理,不再进行传递。

更多细节分析请看任玉刚大神的《android开发艺术探索》这本书的第三章。

1 0
原创粉丝点击