• Android中的事件分发机制总结


    Android 的事件分发机制

    一、View的事件分发总结:

    View的onTouchEvent和OnTouch区别 
    还是以自定义的TestButton为例。 

    我们可以通过重写onTouchEvent方法来处理诸如down move up的消息:

    public class TestButton extends Button {

     

              public TestButton(Context context) {

                        super(context);

                        // TODO Auto-generated constructor stub

              }

             

              public TestButton(Context context, AttributeSet attributeSet) {

                        super(context, attributeSet);

                        // TODO Auto-generated constructor stub

              }

             

              @Override

              public boolean onTouchEvent(MotionEvent event) {

                        boolean value = super.onTouchEvent(event);

                        System.out.println("super.onTouchEvent: " + value+ " event: " + event.getAction());

                        return value;

              }

    也可以通过实现OnTouchListener的接口,然后设置TestButton的onTouchListener可以达到同样的目的 

        class OnTouchListenerTest implements View.OnTouchListener{

                        @Override

                        public boolean onTouch(View v, MotionEvent event) {

                                   return false;

                        }

             

        }

            TestButton b = (TestButton)findViewById(R.id.button);

            OnTouchListenerTest listener = new OnTouchListenerTest();

            b.setOnTouchListener(listener);

    但上述两种监听有什么区别呢?

    先看一下Android源码中对于View中dispatchTouchEvent的实现:

              public boolean dispatchTouchEvent(MotionEvent event){

                        ... ...

                        if(onFilterTouchEventForSecurity(event)){

                                   ListenerInfo li = mListenerInfo;

                                   if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED

                                             && li.mOnTouchListener.onTouch(this, event)) {

                                             return true;

                                   }

                                   if(onTouchEvent(event)){

                                             return true;

                                   }

                        }

                        ... ...

                        return false;

              }


    可以看到onTouchListener的接口的优先级是要高于onTouchEvent的,假若onTouchListener中的onTouch方法返回true,

    表示此次事件已经被消费了,那onTouchEvent是接收不到消息的。

    因为Button的performClick是利用onTouchEvent实现,假若onTouchEvent没有被调用到,那么Button的Click事件也无法响应。


    综合来讲:

    onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。

    假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。

    内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。

    二、ViewGroup 的事件分发总结: 

    1、基础知识

    (1) 所有 Touch 事件都被封装成了 MotionEvent 对象,包括 Touch 的位置、时间、历史记录以及第几个手指(多指触摸)等。

    (2) 事件类型分为 ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以 ACTION_DOWN 开始 ACTION_UP 结束。

    (3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和 OnTouchListener

    2、传递流程

    (1) 事件从 Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的 View(ViewGroup)开始一直往下(子 View)传递。子 View 可以通过 onTouchEvent()对事件进行处理。

    (2) 事件由父 View(ViewGroup)传递给子 View,ViewGroup 可以通过 onInterceptTouchEvent()对事件做拦截,停止其往下传递。

    (3) 如果事件从上往下传递过程中一直没有被停止,且最底层子 View 没有消费事件,事件会反向往上传递,这时父 View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到 Activity 的 onTouchEvent()函数。

    (4) 如果 View 没有对 ACTION_DOWN 进行消费,之后的其他事件不会传递过来。

    (5) OnTouchListener 优先于 onTouchEvent()对事件进行消费。
    上面的消费即表示相应函数返回值为 true。

  • 相关阅读:
    转:5个AJAX Loading动画图标生成器
    小练习:图片轮播jQuery版
    找不同,在一定范围内找出不同数最小的数组。
    一个Hibernate的Hello World, 基于Hibernate 4.0
    队列的操作, 计算要出队某个数需要移动的距离.
    使用反射操作私有(Private)方法和属性
    求由色子组成的立方体的5个可见面(底部不算)中所有数字最小之和.
    动态代理的简单实例.
    设计模式:Java的代理模式.
    Java的反射 基础+简单复制对象实例
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/4800557.html
Copyright © 2020-2023  润新知