zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 高精度乘法
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    Java实现 蓝桥杯VIP 算法提高 现代诗如蚯蚓
    ddd
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/4800557.html
Copyright © 2011-2022 走看看