于android于。主要活动包括点击、按、拖累、滑动等操作,这些构成了Android事件响应,总体而言,,所有事件由例如以下三部分构成的基础:

按(action_down),搬家(action_move),抬起(action_up)。View以及ViewGroup的,这两者中响应的方法分别有:

View.java中:

publi boolean dispatchTouchEvent(MotionEvent event)

public boolean onTouchEvent(MotionEvent event)

ViewGroup.java中

public boolean dispatchTouchEvent(MotionEvent event)

public boolean onTouchEvent(MotionEvent event) 

public boolean onInterceptTouchEvent(MotionEvent event)

在组件嵌套的情况下,对于事件的响应处理会从最顶层的组件不断向子组件传递,一直到最后的View组件。

能够看到ViewGroup中比View中多出了一个onInterceptTouchEvent方法。这是由于ViewGroup组件能够存在子组件,因此须要通过Intercept推断是否将该事件传递到子组件中。

函数的详细功能例如以下:

onTouchEvent是真正用来进行业务逻辑处理的地方,返回true表示已经将该事件消费。返回false表明事件继续传递。

onInterceptTouchEvent是用来进行推断是否须要对事件进行拦截从而阻止其继续往子组件传递的,返回false表示无需拦截,则递归的调用子组件的dispatchTouchEvent方法;返回true表示须要拦截,则直接调用本组件的onTouchEvent方法进行处理。

以上两个的功能相对好理解一些,最基本的是第三个。之前在网上看了非常多。可是都没有讲的特别清楚的。

大都说是用于事件分发的,返回true表示不继续分发,返回false表示继续分发。可是一直没讲明确这个跟採用onInterceptTouchEvent的差别在哪里。。

直接点说,Android对于touch事件的处理是通过递归来进行的。而这样的递归就体如今dispatchTouchEvent上。以上所写的两个函数就是在dispatchTouchEvent中被调用而且运行从而实现其分发的业务逻辑的。

在dispatchTouchEvent中有可能会调用三个方法:

1、本组件的onInterceptTouchEvent

2、子组件的dispatchTouchEvent

3、本组件的onTouchEvent

ViewGroup中dispatchTouchEvent()详细的运行逻辑:

1、首先运行本组件的onInterceptTouchEvent。假设返回false,表明无需拦截。则调用第二个方法。即子组件的dispatchTouchEvent方法;假设返回true,无需向子组件传递。则直接调用本组件的onTouchEvent方法

2、第一步中假设须要向子组件传递事件。假设递归调用子组件的dispatchTouchEvent返回false,则调用本组件的onTouchEvent方法。假设返回true,则无需调用本组件的onTouchEvent方法

3、依据前两步的运行结果,将该dispatchTouchEvent的返回值返回给父组件的dispatchTouchEvent方法。

view中的dispatchTouchEvent会直接调用其自身的onTouchEvent。

一般没有必要重写dispatchTouchEvent方法,假设一定要重写。请注意调用super.dispatchTouchEvent()方法。否则递归调用到此处即停止。

在不考虑dispatchTouchEvent的情况下,简单的运行流程是这种:

最顶层的组件首先响应事件,然后不断向子组件进行传递,调用子组件的onInterceptTouchEvent方法,一直到某个组件A的onInterceptTouchEvent方法返回true或者到达了view组件,然后调用该组件的onTouchEvent方法,之后不断向父组件进行返回,调用父组件的onTouchEvent直到某个父组件的onTouchEvent方法返回true。

事实上就是个首先从父组件不断向下调用onInterceptTouchEvent,然后从子组件不断向上调用onTouchEvent的过程。

还须要注意的:

1、假如这个过程中某个组件截获并处理了ACTION_DOWN事件。则之后对应的ACTION_MOVE、ACTION_UP等其它事件将不再会被传递到他的子孙组件,而是传递到该组件后就运行返回的流程。

2、假设某个组件的onInterceptTouchEvent对ACTION_DOWN返回true。则之后的ACTION_MOVE,ACTION_DOWN等将不会再运行本onInterceptTouchEvent。而是直接传递给本组件的onTouchEvent,可是依旧会经过其父组件的onInterceptTouchEvent。

过程中看到有篇文章里对dispatchTouchEvent的代码进行了凝视,能够更清楚的说明问题。详细例如以下。引用地址为:http://blog.csdn.net/hdxiaoyu2/article/details/25563453

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
} // Check for interception.
final boolean intercepted;//拦截的标记变量
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) { //调用自身的 onInterceptTochEvent。推断是否须要拦截
intercepted = onInterceptTochEvent(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;
} //假如没拦截
if (!canceled && !intercepted) {
if (actionMasked == MotionEvent.ACTION_DOWN
|| (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) { if (newTouchTarget == null && childrenCount != 0) {
final float x = ev.getX(actionIndex);
final float y = ev.getY(actionIndex);
// Find a child that can receive the event.
// Scan children from front to back.
final View[] children = mChildren; final boolean customOrder = isChildrenDrawingOrderEnabled();
//遍历全部的子View,而且调用他们的事件分发方法dispatchTouchEvent() for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
final View child = children[childIndex];
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
} newTouchTarget = getTouchTarget(child);
//newTouchTarget表示事件传递的View目标。当不为空的时候,直接跳出循环
if (newTouchTarget != null) { newTouchTarget.pointerIdBits |= idBitsToAssign;
break;
} resetCancelNextUpFlag(child);
//递归调用子View分发事件方法,
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { mLastTouchDownTime = ev.getDownTime();
mLastTouchDownIndex = childIndex;
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
//设置分发目标newTouchTarget为当前View
newTouchTarget = addTouchTarget(child, idBitsToAssign);
//标记子View的分发结果,为True的话。以下的代码是不会调用当前View的onTouch方法的,也就是规则1生成的原因
alreadyDispatchedToNewTouchTarget = true;
break;
}
}
} }
} if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
} else {
// Dispatch to touch targets, excluding the new touch target if we already
// dispatched to it. Cancel touch targets if necessary.
TouchTarget predecessor = null;
TouchTarget target = mFirstTouchTarget;
while (target != null) {
final TouchTarget next = target.next; //假设刚才alreadyDispatchedToNewTouchTarget设为True的话。就不运行以下的dispatchTransformedTouchEvent
//alreadyDispatchedToNewTouchTarget是由子View的onTouch返回值决定的, if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
handled = true;
} else {
final boolean cancelChild = resetCancelNextUpFlag(target.child)
|| intercepted; //运行自身的Touch事件,
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessor == null) {
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
}
predecessor = target;
target = next;
}
}
}

另外还看到两篇将的不错的。能够作为參考:

http://www.infoq.com/cn/articles/android-event-delivery-mechanism

http://blog.csdn.net/hdxiaoyu2/article/details/25563453

http://yizhi401.blog.51cto.com/6500239/1364958

版权声明:本文博主原创文章,博客,未经同意不得转载。

Android MotionEvent事故响应机制的更多相关文章

  1. Android MotionEvent事件响应机制

    在android中,事件主要包括点击.长按.拖曳.滑动等操作,这些构成了Android的事件响应,总体来说,所有的事件都由如下三个部分作为基础构成: 按下(action_down),移动(action ...

  2. Android之事件分发机制

    本文主要包括以下内容 view的事件分发 viewGroup的事件分发 首先来看两张图 在执行touch事件时 首先执行dispatchTouchEvent方法,执行事件分发. 再执行onInterc ...

  3. Android View 事件分发机制详解

    想必很多android开发者都遇到过手势冲突的情况,我们一般都是通过内部拦截和外部拦截法解决此类问题.要想搞明白原理就必须了解View的分发机制.在此之前我们先来了解一下以下三个非常重要的方法: di ...

  4. Android平台的事件处理机制和手指滑动例子

    Android平台的事件处理机制有两种 基于回调机制的事件处理:Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通过重写View中的这些回调方法来实现需要的响应事件. 基于 ...

  5. Android 的事件传递机制,详解

    Android 的事件传递机制,详解 前两天和一个朋友聊天的时候.然后说到事件传递机制.然后让我说的时候,忽然发现说的不是非常清楚,事实上Android 的事件传递机制也是知道一些,可是感觉自己知道的 ...

  6. Android触摸事件传递机制

    简单梳理一下Android触摸事件传递机制的知识点. 一.View与ViewGroup的关系 View和ViewGroup二者的继承关系如下图所示: View是Android中最基本的一种UI组件,它 ...

  7. 使用Android SwipeRefreshLayout了解Android的嵌套滑动机制

    SwipeRefreshLayout 是在Android Support Library, revision 19.1.0加入到support v4库中的一个下拉刷新控件,关于android的下拉刷新 ...

  8. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  9. Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)

      ViewGroup View  Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 无 无 onTouchEvent 有 有 有 例 ...

随机推荐

  1. QT Programming 1

    1.控制台输出 helloworld #include<QtCore/QCoreApplication> #include<QDebug> int main(int argc, ...

  2. Android四个存储数据的SharedPreferences

    除了SQLite外部数据库.SharedPreferences它是一个轻量级的数据存储,其本质是基于XML文件存储key-value键值数据,通过定期用它来存储一些简单的配置信息.它的存储位置/dat ...

  3. 简述负载均衡&CDN技术(转)

    曾经见到知乎上有人问“为什么像facebook这类的网站需要上千个工程师维护?”,下面的回答多种多样,但总结起来就是:一个高性能的web系统需要从无数个角度去考虑他,大到服务器的布局,小到软件中某个文 ...

  4. oracle12c(oracle12.1.0.1.0)安装指南--实测OEL5.9(RH5)

    [root@oel ora12c]# uname -a Linux oel 2.6.39-300.26.1.el5uek #1 SMP Thu Jan 3 18:31:38 PST 2013 x86_ ...

  5. ios发电子邮件

    ios发电子邮件 by 吴雪莹 第一: NSString *myEmail = @"3423423423@qq.com"; NSString *toemail = @"a ...

  6. IIS的WebGarden、WebFarm和StateServer

    开启IIS的WebGarden.WebFarm和StateServer之旅 前言 公司系统虽然配置有1台NLB后拖4台App Server最后搭一台强劲无比的DB Server,但每天下午4点左右总被 ...

  7. 新项目架构从零开始(三)------基于简单ESB的服务架构

    这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ...

  8. POJ1274 The Perfect Stall【二部图最大匹配】

    主题链接: id=1274">http://poj.org/problem? id=1274 题目大意: 有N头奶牛(编号1~N)和M个牛棚(编号1~M). 每头牛仅仅可产一次奶.每一 ...

  9. T-SQL基础(7) - 透视,逆透视和分组集

    透视转换: use tempdb;if object_id('dbo.Orders', 'U') is not null drop table dbo.Orders;create table dbo. ...

  10. 解析DBR操作系统引导记录数据

    理解文件系统.你必须要熟悉DBR,下面我们就来看看文件系统解析DBR数据. Dos Boot Record(DBR)操作系统引导记录是由操作系统的格式化程序建立的.在文件系统驱动操作不论什么一个磁盘卷 ...