android触摸事件分发机制

一、Android触摸事件分发机制概述:

Android如此受欢迎,就在于其优秀的交互性,这其中,Android优秀的事件分发机制功不可没。那么,作为一个优秀的程序员,要想做一个具有良好交互性的应用,必须透彻理解Android的事件分发机制。

要想充分理解android的分发机制,需要先对以下几个知识点有所了解:

①   View和ViewGroup什么?

②   事件

③   View 事件的分发机制

④   ViewGroup事件的分发机制

下面,就让我们沿着大致方针,开始事件分发的探究之旅吧……

二、View和ViewGroup:

Android的UI界面都是由View和ViewGroup及其派生类组合而成的。其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的,也就是说ViewGroup的父类就是View。

通常来说,Button、ImageView、TextView等控件都是继承父类View来实现的。RelativeLayout、LinearLayout、FrameLayout等布局都是继承父类ViewGroup来实现的。

事件:

当手指触摸到View或ViewGroup派生的控件后,将会触发一系列的触发响应事件,如:

onTouchEvent、onClick、onLongClick等。每个View都有自己处理事件的回调方法,开发人员只需要重写这些回调方法,就可以实现需要的响应事件。

而事件通常重要的有如下三种:

MotionEvent.ACTION_DOWN  按下View,是所有事件的开始

MotionEvent.ACTION_MOVE   滑动事件

MotionEvent.ACTION_UP       与down对应,表示抬起

三、事件传递的三个阶段

  1> 事件分发(dispatch):事情的分发对应着dispatchTouchEvent方法,android系统中,所有的触摸事件都是通过这个方法来分发的,方法原型如    下:public boolean dispatchTouchEvent(MotionEvent ev)

   方法返回值为true表示事件被当前视图消费掉,不在分发事件;方法返回值为super.dispatchTouchEvent表示继续分发该事件 。如果当前视图是ViewGroup及其子类,则会调用onInterceptTouchEvent方法判定是否拦截该事件。

  2> 事件拦截(Intercept):事件的拦截对应着onInterceptTouchEvent方法,这个方法只在ViewGroup及其子类中才存在,在View和Activity中是不存在的。方法的原形如下:public boolean onInterceptTouchEvent(MotionEvent ev)

   方法返回true表示拦截事件,不继续分发给子视图,同时交由自身的onTouchEvent方法进行消费,返回false或super.onInterceptTouchEvent 

表示不对事件进行拦截,需要继续传递给子视图

  3> 消费(Consume):事件的消费对应着onTouchEvent方法,方法原型为

   public boolean onTouchEvent(MotionEvent event)

   方法返回值为false表示当前视图不处理这个事件,处理会被传递给父视图的onTouchEvent方法进行处理。

在android系统中,拥有事件传递处理能力的类有以下三种

 Activity:拥有dispatchTouchEvent(Activity的dispatchTouchEvent放回的如果是true或false的时候将不会继续分发事件)和onTouchEvent两个         方法

 ViewGroup:拥有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三个方法

 View:拥有dispatchTouchEvent和onTouchEvent两个方法

四、触摸事件传递的传递顺序如下:

    触摸事件的传递顺序是由Activity到ViewGroup,再由ViewGroup递归传递给它的子View。

    ViewGroup通过onIterceptTouchEvent方法针对事件进行拦截,如果该方法返回true,则事件不会继续传递给子View,如果返回false或者

 super.onInterceptTouchEvent,则事件会继续传递给子View。

    在子View中对事件进行消费后,ViewGroup将接收不到任何事件。  

五、TouchEvent事件传递顺序

1
2
3
dispatchTouchEvent      事件的分发操作
TouchEvent          事件处理
onInterceptTouchEvent           事件拦截操作

在Activity与View中,TouchEvent的传递会先经过 dispatchTouchEvent,然后再到onTouchEvent
在ViewGroup中,有点特殊,在dispatchTouchEvent与onTouchEvent之间,还会经过onInterceptTouchEvent这个方法

1
2
3
4
5
6
7
8
MotionEvent.ACTION_DOWN的传递
     ①Activity.dispatchTouchEvent
     ②ViewGroup.dispatchTouchEvent
     ③ViewGroup.onInterceptTouchEvent
     ④View.dispatchTouchEvent
     ⑤View.onTouchEvent (如果这里返回 true ,后续的MOVE,UP事件都会传递到这里处理,否则继续向下传递)
     ⑥ViewGroup.onTouchEvent (如果这里返回 true ,后续的MOVE,UP事件会通过ViewGroup.dispatchTouchEvent都会直接传递到这里处理,不在向下传递,否则继续向下传递)
     ⑦Activity.onTouchEvent (如果事件经过了GroupView,View,还是传到了这里,不管这里返回的是 false 还是 true ,后续的MOVE,UP事件都会直接通过Activity.dispatchTouchEvent传递到这里)

 dispatchTouchEvent方法测试 1

1
2
3
4
@Override
public  boolean  dispatchTouchEvent(MotionEvent event) {
     return  ( true  ||  false );      // 直接返回true或者false
}

经测试在dispatchTouchEvent方法,如果没有super.dispatchTouchEvent(event)也就是没有继续父类的实现,
这里返回true,那么事件都会传到这里结束。
这里返回false,事件会直接抛到上一层的onTouchEvent事件中
{ // 说明
    在Activity的dispatchTouchEvent返回false,事件直接结束
    在ViewGroup的dispatchTouchEvent返回false,事件会直接传递到Activity.onTouchEvent中
    在View的dispatchTouchEvent返回false,事件会直接传递到ViewGroup.onTouchEvent中
}

dispatchTouchEvent方法测试 2

1
2
3
4
5
@Override
public  boolean  dispatchTouchEvent(MotionEvent event) {
     super .dispatchTouchEvent(event);
     return  ( true  ||  false );      // 直接返回true或者false
}

测试在dispatchTouchEvent方法中加上super.dispatchTouchEvent(event)这一行
这里返回true,事件会像常规一样去传递,但是最终会传到这一层的onTouchEvent结束,相当于本层的onTouchEvent返回了true
这里返回false,事件会像常规一样去传递,最终于会在哪一层的onTouchEvent返回true结束,随便事件就会直接到那一层的onTouchEvent

ViewGroup.onInterceptTouchEvent
在这个方法中,返回true事件将会被拦截直接传递到ViewGroup的onTouchEvent中处理
在这个方法中,返回false事件向常规一样处理




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 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
发出的红包

打赏作者

优雅的心情

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

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

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

打赏作者

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

抵扣说明:

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

余额充值