Android事件分发机制浅谈

春衣少年当酒歌,起舞四顾以笑和。这篇文章主要讲述Android事件分发机制浅谈相关的知识,希望能为你提供帮助。
---恢复内容开始---
一、是什么
          我们首先要了解什么是事件分发,通俗的讲就是,当一个触摸事件发生的时候,从一个窗口到一个视图,再到一个视图,直至被消费的过程。
二、做什么
                在深入学习android的过程中,我们往往不知道为什么要去学习这些理论,它们枯燥,难懂,甚至在我们处于初级阶段进行开发时完全用不到这些理论。
        所以我们要学会一些技术,要知道它能做些什么。
                比较简单的,在做开发时,如何处理滑动冲突的问题。
三、事件分发机制的分析。
                  首先在这里,这一节不过多的分析事件分发的源码了,在下一节分析,有兴趣的可以去看一看郭霖的博客,对源码分析讲的非常清楚,在这里我主要讲解一些我自己对它的理解。
                  我们先在这里认识三个方法
                  dispatchTouchEvent(MotionEvent ev) //用来进行事件的分发
                  onInterceptTouchEvent(MotionEvent ev) //在dispatchTouchEvent()中调用,用来判断是否拦截某个事件
【Android事件分发机制浅谈】                  onTouchEvent(MotionEvent ev)      //在dispatchTouchEvent()中调用,用来处理点击事件
                  //伪代码分析,便于理解
                  public boolean dispatchTouchEvent(MotionEvent ev){
                                boolean consume = false;
                                if(onInterceptTouchEvent(ev)){
                                          consume  = onTouchEvent(ev);  
                                }  else{
                                          consum = child.dispatchTouchEvent(ev);
                                }
return consum;
                  }
 
                首先我们将事件分发机制按两个主角分开讲,一个是ViewGroup,一个是View。
                对于ViewGroup而言
                  当一个点击事件产生后,dispatchTouchEvent()方法调用。如果onInterceptTouchEvent()方法返回true表示事件被拦截,返回false则该事件会交给子View继续执行上述步骤,直至事件被处理。
                对于View而言
处理事件,设置onTouchEventListener(),onTouch()回调,返回false,onTouchEvent()会被调用,若此时设置了setOnClickListener(),则onClick()方法会被调用。返回true,onTouchEvent()不会被调用,此时设置了setOnClickListener(),则onClick()方法并不会被调用。这便是View的分发机制
 
 
                简单来说上面两部分构成了事件分发机制,由于并没有分析源码,所以看起来很简单,画出流程图来说是这样的
               

Android事件分发机制浅谈

文章图片

                 
            学习了这一节后,想必对android事件分发有了大致的了解,但可能还会有疑问,比如onClick方法为什么有时候设置了也不会被调用,等等问题,我会在接下来分析源码。
 
          补充:1、点击事件产生后,遵循如下顺序 Activity-> Window-> View
                            2、当所有View都不处理事件时(onTouchEvent()返回false),事件会交还给Activity处理
3、onTouch和onTouchEvent,都是在dispatchTouchEvent()中调用,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。另外需要注意的是,onTouch能够得到执行需要两个前提条件,第一mOnTouchListener的值不能为空,第二当前点击的控件必须是enable的。因此如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。

    推荐阅读