Android事件分发详解

来源:互联网 发布:网络心理学的杂志 编辑:程序博客网 时间:2024/06/04 19:09

这几天了解android的事件分发机制,有了一点感触记录下来:

下面是我参考的网址:

http://blog.csdn.net/guolin_blog/article/details/9097463#reply

http://v.youku.com/v_show/id_XODQ1MjI2MDQ0.html

个人感觉第一篇写的挺好的,但是还有些不足,我在他的基础上进行补充,大家可以看下他的博客,再来看我的。


android的整个事件分发机制流程图:

具体过程我先说明,等下用代码说明:

当点击界面上的button时,产生Action_down事件,会先调用Activity的dispatchTouchEvent()对事件进行检测,然后依次从上往下调用ViewGroup,View的dispatchTouchEvent(), 然后从下往上依次调用onTouchEvent(),如果在向上传递过程中,某一级的onTouchEvent()处理事件并且返回true,那么后面的传递就不会进行了。


代码验证: 这个布局是只有一个自定义的button

public class MainActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("msg","Activity-->onTouchEvent");
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("msg","Activity-->dispatchTouchEvent");
       return super.dispatchTouchEvent(event);
    }
}


public class MyButton extends Button {
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i("msg","View-->dispatchTouchEvent");
       return super.dispatchTouchEvent(event);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("msg","View-->onTouchEvent");
        return false;
    }
}



public class MyFrameLayout extends FrameLayout {
    public MyFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("msg","ViewGroup-->dispatchTouchEvent");
       return super.dispatchTouchEvent(event);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("msg","ViewGroup-->onTouchEvent");
        return false;
    }
}


当手指按在button上不动,只触发Action_down事件,log如下

当手指up时,输出如下

up相比down只增加了2条,直接执行Activity的dispatchTouchEvent()和onTouchEvent(),  原因就是android系统觉得down事件都消费那么up事件就没必要传递了,直接给Activity执行所以中间有几步直接跳过了。


下面将MyButton中的onTouchEvent()返回值修改为true,消费down事件,得到的结果:

up之后的结果是:



可以看到down和up的结果是一样的,都只执行到了myButton的onTouchEvent()将事件直接消费了,所以后面就没有传递了。

我在这里只是说清了整个整体的流程,如果大家要研究源码细节可以参考这篇:http://blog.csdn.net/guolin_blog/article/details/9097463#reply

这里介绍了dispatchTouchEvent(), onTouch() ,onTouchEvent() 三者之间的具体联系。


除此之外,介绍ViewGroup的onInterceptTouchEvent(),  方法主要是对触发事件进行拦截,让事件无法向后传递,大家在实际操作中ScrollView中含有button,移动button时,触发的是ScrollView的事件,而不是button, 照我上面说的,只要button中的onTouchEvent()进行消费的话,应该会优先执行,但是这里是ScrollView消费的,主要原因是在ScrollView中当监听到Move事件的换,在ScrollView的onInterceptTouchEvent()返回true,对事件进行了拦截,自己进行了处理。 但是如果将ScrollView换成FrameLayout,那么就是另一种结果,FrameLayout的onInterceptTouchEvent()默认返回false,所以可以分发。




0 0