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事件分发和消费源码简单理解
(0)

相关推荐

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

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

  • Android View事件分发机制详解

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

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

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

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

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

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

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

  • Android View 事件分发机制详解

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

  • Android View的事件分发机制

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

  • Android View的事件分发详解

    1.前言 近两天学习了一下view的事件分发,把自己的理解总结了一遍,只表达了自己认为需要明白的地方,毕竟是菜鸟一枚,不对的地方还请大神们多指教! 2.三个方法 public boolean dispatchTouchEvent(MotionEvent ev) 用于事件的分发,返回结果受以下两个方法的影响,表示是否消耗了事件. public boolean onInterceptTouchEvent(MotionEvent ev) 事件是否被拦截,返回true表示拦截,false表示不拦截 pu

  • 如何自己实现Android View Touch事件分发流程

    Android Touch事件分发是Android UI中的重要内容,Touch事件从驱动层向上,经过InputManagerService,WindowManagerService,ViewRootImpl,Window,到达DecorView,经View树分发,最终被消费. 本文尝试通过对其中View部分的事件分发,也是与日常开发联系最紧密的部分,进行重写.说是重写,其实是对Android该部分源码进行大幅精简而不失要点,且能够独立运行,以一窥其全貌,而不陷入到源码繁杂的细节中. 以下类均为

  • Android 事件分发详解及示例代码

    事件分发是Android中非常重要的机制,是用户与界面交互的基础.这篇文章将通过示例打印出的Log,绘制出事件分发的流程图,让大家更容易的去理解Android的事件分发机制. 一.必要的基础知识 1.相关方法 Android中与事件分发相关的方法主要包括dispatchTouchEvent.onInterceptTouchEvent.onTouchEvent三个方法,而事件分发一般会经过三种容器,分别为Activity.ViewGroup.View.下表对这三种容器分别拥有的事件分发相关方法进行

  • Android编程输入事件流程详解

    本文实例讲述了Android编程输入事件流程.分享给大家供大家参考,具体如下: EventHub对输入设备进行了封装.输入设备驱动程序对用户空间应用程序提供一些设备文件,这些设备文件放在/dev/input里面. EventHub扫描/dev/input下所有设备文件,并打开它们. bool EventHub::openPlatformInput(void) { ... mFDCount = 1; mFDs = (pollfd *)calloc(1, sizeof(mFDs[0])); mDev

  • Android View 绘制机制的详解

    View 绘制机制一. View 树的绘图流程 当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android framework 处理.绘制是从根节点开始,对布局树进行 measure 和 draw.整个 View 树的绘图流程在ViewRoot.java类的performTraversals()函数展开,该函数所做 的工作可简单概况为是否需要重新计算视图大小(measure).是否需要重新安置视图的位置(layout).以及是否需要重绘(draw),流程图如下: Vie

  • 解析Android点击事件分发机制

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

  • Android View的事件体系教程详解

    目录 一.什么是View?什么是ViewGroup? 二.View的位置 三.View的触摸事件 1.MotionEvent 2.TouchSlop 3.VelocityTracker 5.Scroller 四.View的滑动 1)使用Scroll 2)通过动画 3)使用延时策略 五.View的事件分发机制 六.View的滑动冲突问题 View的滑动冲突常见可以简单分为三种: 滑动冲突的处理规则 滑动冲突的解决方法 一.什么是View?什么是ViewGroup? View是Android中所有控

  • Android开发使用RecyclerView添加点击事件实例详解

    目录 引言 一.RecyclerView基本使用 1. 添加适配器Adapter 2. 创建列表的每个项的item_layout.xml文件 3. 在activity中使用 二.RecyclerView点击事件详细步骤 1. 在RecyclerView对应的Adapter类里面新建接口 2. 在Adapter类里创建setOnItemClickListener方法 3. 在Adapter类的onBindViewHolder里给每个item设置回调 4. 在RecyclerView对应的Activ

  • Android自定义view实现侧滑栏详解

    目录 前言 需求 效果图 编写代码 主要问题 前言 上一篇文章学了下自定义View的onDraw函数及自定义属性,做出来的滚动选择控件还算不错,就是逻辑复杂了一些.这篇文章打算利用自定义view的知识,直接手撕一个安卓侧滑栏,涉及到自定义LayoutParams.带padding和margin的measure和layout.利用requestLayout实现动画效果等,有一定难度,但能重新学到很多知识! 需求 这里类似旧版QQ(我特别喜欢之前的侧滑栏),有两层页面,滑动不是最左侧才触发的,而是从

随机推荐