Android 事件分发机制探析

一基础知识

android的事件处理分为3步。

1)public booleandispatchTouchEvent(MotionEvent ev)  这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP

二事件探析

场景:本想实现ttdt那种滑动页面结束activity的效果,摸索了好久终于实现,流畅效果很满意,但是activity布局上添加其他控件,比如giriView\listView等,会出现等层自己写的那个View获取不到焦点,导致滑动事件失效。

分析:当在顶层View上加其他View,默认情况都是顶层的事件要传给最上面的view处理,导致为处理情况下,我做的效果失效了;

下图为一个正常的View点击效果图:



1、ViewGroup3的dispatchTouchEvent()方法会被调用。
	2、ViewGroup3调用ViewGroup2的dispatchTouchEvent()方法。
	3、ViewGroup2调用ViewGroup1的dispatchTouchEvent()方法。
	4、ViewGroup1会调用View1的dispatchTouchEvent()方法。
	5、View1的dispatchTouchEvent()方法调用自己的onTouchEvent()方法。在onTouchEvent方法中处理点击事件。处理完了后会返回一个true给调用它的dispatchTouchEvent()方法。
	6、ViewGroup1的dispatchTouchEvent()方法会返回一个true值给ViewGroup2的dispatchTouchEvent()方法。这样一直将则个true值返回到ViewGroup3的dispatchTouchEvent()方法。ViewGroup3在将这个值返回给调用它的方法。这样一个事件分发过程结束。
三问题解决
想到这里,基本上我们就可以利用View的分发拦截机制,将我们需要的Event拦截,不需要的转发。
在自己写的view重写onInterceptTouchEvent()在里面做下操作:
@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                mLastDownX = (int) ev.getX();
                System.err.println("ACTION_DOWN=" + mLastDownX);
                return true;

        }
        return super.onInterceptTouchEvent(ev);
    }

四验证效果
运行程序,看效果,完美实现,流畅滑动,可以达到ttdt效果!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。