Android事件分发机制

版权声明:本文为openXu原创文章【openXu的博客】,未经博主允许不得以任何形式转载

   在平时的工作中,事件分发机制是非常重要的,之前虽然说比较了解,出现问题也能得到解决,但是一直没有系统的总结一下,有些地方也不能一句话说死,今天得空简单的总结记录如下:

相关类及方法

     这里写图片描述

重要方法的作用

  **dispatchTouchEvent():**此方法是View中定义的,ViewGroup重写了它。View中dispatchTouchEvent()将事件交给OnTouchListener处理,并调用onTouchEvent(),这些都是让控件自己处理事件;而ViewGroup中dispatchTouchEvent()是将事件分发给他的子控件处理,如果子控件没有消费掉事件,然后再自己处理,自己处理的方式跟View中一样(最后调用的是super.dispatchTouchEvent() )

  onInterceptTouchEvent(ev): ViewGroup的方法,是否拦截事件,如果返回true,则子控件无法获得事件
  setOnTouchListener(): View中的方法,设置Touch监听,回调onTouch()方法
  onTouchEvent(): View中的方法,解析处理事件
  setOnClickListener(): View中的方法,设置点击事件,回调onClick()方法

方法调用图

     这里写图片描述

分析

  Android事件的传递是从外层控件传递到内层控件(父控件传子控件)的,屏幕收到事件后首先传递给最外层的容器,调用它的dispatchTouchEvent()方法,dispatchTouchEvent()是View中的方法,ViewGroup重写了它。

  ViewGroup的dispatchTouchEvent()首先判断事件拦截是否被禁用掉了(通过disallowIntercept,此值默认是false,可以通过requestDisallowInterceptTouchEvent()设置),如果没被禁用,则会调用onInterceptTouchEvent()判断事件是否被拦截。如果外层控件的onInterceptTouchEvent()返回true,事件则不会继续往下传递,如果返回false(和不禁用一样)则事件不会被拦截,会遍历它的子控件,判断触摸点是否在子控件范围内。

  ①、如果在,就会调用子控件的dispatchTouchEvent(),子控件如果是容器又会重复上面步骤,如果不是容器,就会执行View的dispatchTouchEvent(),下面插播View的dispatchTouchEvent()分析:

  View对dispatchTouchEvent()的实现判断控件是否可用(enable)&& 是否设置了OnTouchListener,如果为true会调用监听的onTouch(),onTouch()如果返回false,说明事件没有被消费掉,会继续调用onTouchEvent()方法。

public boolean dispatchTouchEvent(MotionEvent event) {
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
            mOnTouchListener.onTouch(this, event)) {
        return true;
    }
    return onTouchEvent(event);
}

  **onTouchEvent():**该方法会解析一系列的ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件(按下、滑动、抬起等),在ACTION_UP时会调用performClick()方法,该方法判断有没有setOnClickListener,如果设置了就会回调onClick()方法。这个方法也有返回值,如果在某个action返回了false,则后面就不会再执行该方法了(收不到事件了)。

  如果子控件可点击或者需要接受事件,onTouchEvent()一定会返回true,这样在ViewGroup的dispatchTouchEvent()中收到子控件的返回值后也继续返回true,事件到此终止。

  ②、如果不在任何子控件范围内(点击空白处),或者子控件没有处理掉事件(dispatchTouchEvent()返回false),则ViewGroupdispatchTouchEvent()会继续往下执行调用super.dispatchTouchEvent()(View中的dispatchTouchEvent()),这也就是ViewGroup自己处理事件

    这里写图片描述

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
#前言 之前笔者其实已经写过事件分发机制的文章:[快速理解android事件传递拦截机制概念](http://blog.csdn.net/double2hao/article/details/51541061) 但是,现在看来其实更像是一篇知识概括,多出可能未讲清楚,于是打算重写事件分发,用一篇文章大致讲清楚。 首先,形式上笔者最先思考的是使用源码,此者能从原理上讲解分发机制,比起侃侃而谈好得多。但是源码的复杂往往会让新手产生畏惧难以理解,于是笔者最终还是打算使用实例log来让读者理解android事件分发。 #重要函数 笔者此次主要提及最常用的几个函数: (其间区别看源码很容易理解,此处直接给上结果) **onClick():**这个函数是是View提供给我们的OnClickListener这个接口中的函数,在这里可以自定义对点击事件的处理逻辑。会在onTouchEvent()中进行调用。 **onTouch():**这个函数是View提供给我们的OnTouchListener这个接口中的函数,在这里面可以自定义对触摸事件的处理逻辑。 **onTouchEvent():**这个函数是view内部的触摸事件的处理方式,其间包括获取焦点,调用onClick()等等。 **dispatchTouchEvent():**这个是View的事件分发函数,在ViewGroup中进行重写。在View中其间会调用onTouchEvent(),在ViewGroup中其间会调用onInterceptTouchEvent()和onTouchEvent()。 **onInterceptTouchEvent():**这个函数是事件拦截函数,是ViewGroup才有的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

open-Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值