本文只讨论由触摸触发的事件,暂不讨论轨迹球等事件。
以前写 android ,对事件的处理没有太深入,只是简单的 onTouchEvent 、setOnTouchListener就 ok 了,现在写的 UI ,很多自定义组件,父 view 和子view 都需要接收事件,然后处理,这就要求对事件传递机制有一定的了解。
Android的事件:onClick, onScroll, onFling等等,都是由许多个Touch组成的。其中Touch的第一个状态肯定是 ACTION_DOWN, 表示按下了屏幕, ACTION_MOVE 表示为移动手势 ACTION_UP 表示为离开屏幕 ,本文就着中讨论这三种事件的传递。
在Android中,有一类控件是中还可以包含其他的子控件,这类控件是继承于ViewGroup类,例如:LinearLayout, RelativeLayout。还有一类控件是不能再包含子控件,例如:TextView,Button。
本文以LinearLayout中嵌套LinearLayout,LinearLayout中再嵌套TextView的布局来讨论Touch事件传递机制。
对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。
先来看下布局文件
<?xml version="1.0" encoding="utf-8"?> <com.slid.slidingdemo.view.OuterTouchLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:contentDescription="outerLayout" android:background="#F0F0F0" android:orientation="horizontal" > <com.slid.slidingdemo.view.TouchLinearLayout android:layout_width="fill_parent" android:layout_height="300dp" android:contentDescription="innerLayout" android:background="#A9CDEB" android:orientation="horizontal" > <com.slid.slidingdemo.view.TouchTextView android:id="@+id/preYear" android:background="#5994E6" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:textColor="#ffffff" android:contentDescription="textView" android:text="如果在西安遇见你,那么,我们一定要一起去咸阳机场,不坐飞机,也坐不起飞机,只为感受一下机场的豪华,我会偷偷看几眼空姐,然后对你说:“宝贝儿,她们都没有你漂亮”。" /> </com.slid.slidingdemo.view.TouchLinearLayout> </com.slid.slidingdemo.view.OuterTouchLinearLayout>
OuterTouchLinearLayout,TouchLinearLayout分别重写了onInterceptTouchEvent、onTouchEvent,TouchTextView重写了onTouchEvent,并在Activity里重写了dispatchTouchEvent,onTouchEvent,在其中加入了打印代码,在此偷个懒,少打点字,以A代替Activity,以O代表外层(父)OuterTouchLinearLayout,I代表TouchLinearLayout,T代表 TouchTextView,d代表 dispatchTouchEvent,t代表onTouchEvent,i代表onInterceptTouchEvent。(如Ad代表触发了Activity的dispatchTouchEvent方法)
在TextView上划屏下,记录结果,并分别改变重写方法的返回值,得到如下结果集
0 ad-oi-ii-tt-it-ot-at 2 ad-at-ad-at 1 ad-at
2、a d
0 ad 2 ad-ad-ad 1 ad
3、ad at
0 ad 2 ad-ad-ad 1 ad
4、at
0 ad-oi-ii-tt-it-ot-at 2 ad-at-ad-at 1 ad-at
5、oi
0 ad-oi-ot-at 2 ad-at-ad-at 1 ad-at
6 oi ot
0 ad-oi-ot 2 ad-ot-ad-ot 1 ad-ot
7 ot
0 ad-oi-ii-tt-it-ot 2 ad-ot-ad-ot 1 ad-ot
8 ii
0 ad-oi-ii-it-ot-at 2 ad-at-ad-at 1 ad-at
9 ii it
0 ad-oi-ii-it 2 ad-oi-it-ad-oi-it 1 ad-oi-it
10 it
0 ad-oi-ii-tt-it 2 ad-oi-it 1 ad-oi-it
11 tt
0 ad-oi-ii-tt 2 ad-oi-ii-tt 1 ad-oi-ii-tt
分析这些结果,可以得出结论:
ACTION_DOWN事件首先会传到Activity的dispatchTouchEvent中,若返回false,则事件传递到ViewGroup类的onInterceptTouchEvent,onInterceptTouchEvent如果返回false,则DOWN事件继续向子ViewGroup类的onInterceptTouchEvent传递,如果子View不是ViewGroup类的控件,则传递给子View的onTouchEvent。
另外:只要onInterceptTouchEvent()返回false,而且目标控件View::onTouchEvent()返回true,那么事件的每一个动作(按下、移动、抬起等)会都会首先传递到onInterceptTouchEvent()中。
如果onInterceptTouchEvent返回了true,则DOWN事件传递给VIewGroup的onTouchEvent,不再继续传递,并且之后的后续事件也都传递给它的onTouchEvent。
如果某View的onTouchEvent返回了false,则DOWN事件继续向其父ViewGroup类的onTouchEvent传递;如果返回了true,则后续事件会直接传递给其onTouchEvent继续处理。(后续事件只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent)
Activity的onTouchEvent方法是事件最后被处理的地方。如果不处理,系统将抛弃这个事件。暂时没有发现这个方法的返回值对程序有什么意义。我觉得可以这样理解,就如我们说话给别人听,当所有需要听到的人听到这句话了,那这句话就完成了它的意义,在这之后不管又传了多远,还是被墙壁吸收了,都没啥影响。
相关推荐
android触摸事件传递机制图文详解,自认为最简略最完善的流程图!
以后会按标准一个个的写完测试DEMO,一是自我学习,二是方便同样在学习的其他同学这是,本系列代码均来自《Android高级进阶》,经过测试可以运行,这是 第一章 Android 触摸事件传递机制 View的事件传递机制
Android触摸事件传递机制图解,这个流程详细的受不鸟!
android Touch事件传递机制的实例
今天总结的一个知识点是Andorid中View事件传递机制,也是核心知识点,相信很多开发者在面对这个问题时候会觉得困惑,另外,View的另外一个难题滑动冲突,比如在ScrollView中嵌套ListView,都是上下滑动,这该如何...
一个例子,自己写来用来看看android的触摸事件传递机制,为写滑动菜单打基础。
Android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。
Android触摸事件传递机制及viewpager嵌套fragment冲突处理视频教程,本课程对安卓中的触摸事件分发机制理论进行讲解,并结合开发中常出现的触摸冲突做讲解。
view事件传递机制中,ViewEventActivty这个类 通过输出,可以知道,先执行父控件的dispatch事件,再执行子控件的dispatch事件。 一般顺序是是:父控件的:dispatchTouchEvent,onInterceptTouchEvent,子控件的...
之前笔者其实已经写过事件分发机制的文章:[快速理解android事件传递拦截机制概念](http://blog.csdn.net/double2hao/article/details/51541061) 但是,现在看来其实更像是一篇知识概括,多出可能未讲清楚,于是打算...
上一篇讲了Android触摸事件的传递机制,具体可以看这里初识Android触摸事件传递机制。既然知道Android中触摸事件的传递分发,那么它能解决什么样的问题,在我们实际开发中如何应用,这点很重要,知道原理是为了解决...
主要是parent根据触摸事件的产生位置,以及child是否愿意负责处理该系列事件等状态,向其child分发事件的机制。 2、事件的拦截机制,onInterceptTouchEvent。主要是parent根据它内部的状态、或者child的状态,来把...
这个时候我们就需要了解Android的事件分发机制。 Android的触摸事件分发过程由三个很重要的方法来共同完成:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。我先将这三个方法大体的介绍一下。 •...
Android中事件的传递和拦截和View树结构是相关联的,在View树中,分为叶子节点和普通节点,普通节点有子节点只能是ViewGroup,叶子节点可以是View或者ViewGroup。Android和事件分发拦截相关的方法有 ...
----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...