关闭

android触摸事件分发机制

199人阅读 评论(0) 收藏 举报
分类:

一、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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:41390次
    • 积分:1320
    • 等级:
    • 排名:千里之外
    • 原创:74篇
    • 转载:115篇
    • 译文:0篇
    • 评论:4条
    最新评论