Android View的事件分发详解

1.前言

近两天学习了一下view的事件分发,把自己的理解总结了一遍,只表达了自己认为需要明白的地方,毕竟是菜鸟一枚,不对的地方还请大神们多指教!

2.三个方法

public boolean dispatchTouchEvent(MotionEvent ev)

用于事件的分发,返回结果受以下两个方法的影响,表示是否消耗了事件。

public boolean onInterceptTouchEvent(MotionEvent ev)

事件是否被拦截,返回true表示拦截,false表示不拦截

public boolean onTouchEvent(MotionEvent ev)

表示事件是否被处理

3.三个方法之间的关系

public boolean dispatchTouchEvent(MotionEvent ev){
  boolean result = false;
  if(onInterceptTouchEvent(ev)){
    result = onTouchEvent(ev);
  }else{
    result = child.dispatchTouchEvent(ev);
  }
  return result;
}

4.原理论述

1.同一个事件序列是指从手指接触屏幕开始到离开屏幕那一刻产生的一系列事件,其中以down开始,中间产生若干move事件,最后以up事件结束。
2.同一个事件序列,只能被一个view拦截处理,如果它不消耗down事件,那么其他的事件也不会交给它处理,而且一旦它处理了down事件,以后的事件便不会调用onInterceptTouchEvent此方法判断是否拦截,因为都会交给它处理,就不用再询问了。
3.如果view不消耗除down以外的其他事件,那么这个点击事件会消失,此时父元素的onTouchEvent并不会被调用,并且当前view可以持续接收后续事件,最终这些消失的点击事件将交由activity处理。
4.ViewGrop默认不拦截任何事件。
5.VIew没有onInterceptTouchEvent方法,一旦有点击事件传递给它,那么它的onTouchEvent方法就会调用。
6.View处于不可点击状态时(clickable和longClickable同时为false),onTouchEvent不会消耗事件。除此之外onTouchEvent默认都是消耗事件返回为true的。
7.View的enable属性不影响onTouchEvent的默认返回值
8.事件的传递过程是由外向内的,即事件都是先传递给父元素然后再分发给子元素。通过requestDisallowInterceptTouchEvent方法干预父元素的事件分发过程,但是ACTION_DOWN事件除外。
9.view中的点击事件优先级,高-低:onTouchListener--->onTouchEvent--->onClickListener,当onTouchListener中的onTouch方法返回false时,onTouchEvent才会调用

5.个别源码分析

这是ViewGroup的dispatchTouchEvent中拦截事件的一段源码,主要讲述拦截过程的思路
1.mFirstTouchTarget 表示当事件被ViewGroup的子元素成功处理时,会被赋值,所以一旦ViewGroup拦截事件,则mFirstTouchTarget ==null,则返回true。
2FLAG_DISALLOW_INTERCEPT此标志位是有requestDisallowInterceptTouchEvent方法设置的,一般位于子view中,一旦此标志位设置则不会执行VIewGroup中的onInterceptTouchEvent方法,也就不会拦截除了ACTION_DOWN之外的方法,印证了论述2

// Check for interception.
  final boolean intercepted;
  if (actionMasked == MotionEvent.ACTION_DOWN
      || mFirstTouchTarget != null) {
    final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
    if (!disallowIntercept) {
      intercepted = onInterceptTouchEvent(ev);
      ev.setAction(action); // restore action in case it was changed
    } else {
      intercepted = false;
    }
  } else {
    // There are no touch targets and this action is not an initial down
    // so this view group continues to intercept touches.
    intercepted = true;
  }
  ...
  // Check for cancelation.
  final boolean canceled = resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL;

您可能感兴趣的文章:

  • Android View 事件分发机制详解
  • Android View事件分发机制详解
  • Android事件分发机制(上) ViewGroup的事件分发
  • Android事件分发机制(下) View的事件处理
  • 谈谈对Android View事件分发机制的理解
  • Android View的事件分发机制
  • Android View事件分发和消费源码简单理解
时间: 2017-12-11

谈谈对Android View事件分发机制的理解

最近因为项目中用到类似一个LinearLayout中水平布局中,有一个TextView和Button,然后对该LinearLayout布局设置点击事件,点击TextView能够触发该点击事件,然而奇怪的是点击Button却不能触发.然后google到了解决办法(重写Button,然后重写其中的ontouchEvent方法,且返回值为false),但是不知道原因,这两天看了几位大神的博客,然后自己总结下. public class MyButton extends Button { private

Android View 事件分发机制详解

Android开发,触控无处不在.对于一些 不咋看源码的同学来说,多少对这块都会有一些疑惑.View事件的分发机制,不仅在做业务需求中会碰到这些问题,在一些面试笔试题中也常有人问,可谓是老生常谈了.我以前也看过很多人写的这方面的文章,不是说的太啰嗦就是太模糊,还有一些在细节上写的也有争议,故再次重新整理一下这块内容,十分钟让你搞明白View事件的分发机制. 说白了这些触控的事件分发机制就是弄清楚三个方法,dispatchTouchEvent(),OnInterceptTouchEvent(),o

Android事件分发机制(下) View的事件处理

综述 在上篇文章Android中的事件分发机制(上)--ViewGroup的事件分发中,对ViewGroup的事件分发进行了详细的分析.在文章的最后ViewGroup的dispatchTouchEvent方法调用dispatchTransformedTouchEvent方法成功将事件传递给ViewGroup的子View.并交由子View进行处理.那么现在就来分析一下子View接收到事件以后是如何处理的. View的事件处理 对于这里描述的View,它是ViewGroup的父类,并不包含任何的子元

Android事件分发机制(上) ViewGroup的事件分发

综述 Android中的事件分发机制也就是View与ViewGroup的对事件的分发与处理.在ViewGroup的内部包含了许多View,而ViewGroup继承自View,所以ViewGroup本身也是一个View.对于事件可以通过ViewGroup下发到它的子View并交由子View进行处理,而ViewGroup本身也能够对事件做出处理.下面就来详细分析一下ViewGroup对时间的分发处理. MotionEvent 当手指接触到屏幕以后,所产生的一系列的事件中,都是由以下三种事件类型组成.

Android View事件分发机制详解

准备了一阵子,一直想写一篇事件分发的文章总结一下,这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等,这些子View的外层还有ViewGroup,如RelativeLayout,LinearLayout.作为一个开发者,我们会思考,当点击一个按钮,Android系统是怎样确定我点的就是按钮而不是TextView的?然后还正确的响应了按钮的点击事件.内部经过了一系列什么过程呢? 先铺垫一些知识能更加清晰的理解事件分发机制: 1. 通过setC

Android View事件分发和消费源码简单理解

Android View事件分发和消费源码简单理解 前言: 开发过程中觉得View事件这块是特别烧脑的,看了好久,才自认为看明白.中间上网查了下singwhatiwanna粉丝的读书笔记,有种茅塞顿开的感觉. 很重要的学习方法:化繁为简,只抓重点. 源码一坨,不要指望每一行代码都看懂.首先是没必要,其次大量非关键代码会让你模糊真正重要的部分. 以下也只是学姐的学习成果,各位同学要想理解深刻,还需要自己亲自去看源码. 2.源码分析 由于源码实在太长,而且也不容易看懂,学姐这里就不贴出来了,因为没必

Android View的事件分发机制

一.Android View框架提供了3个对事件的主要操作概念. 1.事件的分发机制,dispatchTouchEvent.主要是parent根据触摸事件的产生位置,以及child是否愿意负责处理该系列事件等状态,向其child分发事件的机制. 2.事件的拦截机制,onInterceptTouchEvent.主要是parent根据它内部的状态.或者child的状态,来把事件拦截下来,阻止其进一步传递到child的机制. 3.事件的处理机制,onTouchEvent.主要是事件序列的接受者(可以是

解析Android点击事件分发机制

开头说说初衷 网上关于点击事件分发的文章一搜一大堆,标题一看,不是"30分钟让你弄明白XXX"就是"这是讲解XXX最好的文章",满怀憧憬与信心,忍不住兴奋的点进去一看,发现不是代码就全是图,我基本上看完了所有相关的文章,结果硬是看了三个小时也没搞懂.所以最后还是决定自己去试一试,看一看点击事件分发到底是怎么个流程,我写的肯定不会比其他文章好多少,但是呢,带着一个初学者的心,去分析这个东西,自己能弄明白的同时,也让想学习这个的人看了之后有些许收获,那就足够了. 运行的

Android从源码的角度彻底理解事件分发机制的解析(上)

其实我一直准备写一篇关于Android事件分发机制的文章,从我的第一篇博客开始,就零零散散在好多地方使用到了Android事件分发的知识.也有好多朋友问过我各种问题,比如:onTouch和onTouchEvent有什么区别,又该如何使用?为什么给ListView引入了一个滑动菜单的功能,ListView就不能滚动了?为什么图片轮播器里的图片使用Button而不用ImageView?等等--对于这些问题,我并没有给出非常详细的回答,因为我知道如果想要彻底搞明白这些问题,掌握Android事件分发机

Android从源码的角度彻底理解事件分发机制的解析(下)

记得在前面的文章中,我带大家一起从源码的角度分析了Android中View的事件分发机制,相信阅读过的朋友对View的事件分发已经有比较深刻的理解了. 还未阅读过的朋友,请先参考Android从源码的角度彻底理解事件分发机制的解析. 那么今天我们将继续上次未完成的话题,从源码的角度分析ViewGroup的事件分发. 首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View和子VewGroup,是And