Android 的事件分发机制

一、View的事件分发总结:

View的onTouchEvent和OnTouch区别 
还是以自定义的TestButton为例。

我们可以通过重写onTouchEvent方法来处理诸如down move up的消息:

public class TestButton extends Button {

public
TestButton(Context context) {

super(context);

//
TODO Auto-generated constructor stub

}

public
TestButton(Context context, AttributeSet attributeSet) {

super(context,
attributeSet);

//
TODO Auto-generated constructor stub

}

@Override

public
boolean onTouchEvent(MotionEvent event) {

boolean
value = super.onTouchEvent(event);

System.out.println("super.onTouchEvent:
" + value+ " event: " + event.getAction());

return
value;

}

也可以通过实现OnTouchListener的接口,然后设置TestButton的onTouchListener可以达到同样的目的

class OnTouchListenerTest implements View.OnTouchListener{

@Override

public
boolean onTouch(View v, MotionEvent event) {

return
false;

}

}

TestButton b = (TestButton)findViewById(R.id.button);

OnTouchListenerTest listener = new OnTouchListenerTest();

b.setOnTouchListener(listener);

但上述两种监听有什么区别呢?

先看一下Android源码中对于View中dispatchTouchEvent的实现:

public
boolean dispatchTouchEvent(MotionEvent event){

...
...

if(onFilterTouchEventForSecurity(event)){

ListenerInfo
li = mListenerInfo;

if(li
!= null && li.mOnTouchListener != null && (mViewFlags &
ENABLED_MASK) == ENABLED

&&
li.mOnTouchListener.onTouch(this, event)) {

return
true;

}

if(onTouchEvent(event)){

return
true;

}

}

...
...

return
false;

}

可以看到onTouchListener的接口的优先级是要高于onTouchEvent的,假若onTouchListener中的onTouch方法返回true,

表示此次事件已经被消费了,那onTouchEvent是接收不到消息的。

因为Button的performClick是利用onTouchEvent实现,假若onTouchEvent没有被调用到,那么Button的Click事件也无法响应。

综合来讲:

onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。

假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。

内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。

二、ViewGroup 的事件分发总结:

1、基础知识

(1) 所有 Touch 事件都被封装成了 MotionEvent 对象,包括 Touch 的位置、时间、历史记录以及第几个手指(多指触摸)等。

(2) 事件类型分为 ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以 ACTION_DOWN 开始 ACTION_UP 结束。

(3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和 OnTouchListener

2、传递流程

(1) 事件从 Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的 View(ViewGroup)开始一直往下(子 View)传递。子 View 可以通过 onTouchEvent()对事件进行处理。

(2) 事件由父 View(ViewGroup)传递给子 View,ViewGroup 可以通过 onInterceptTouchEvent()对事件做拦截,停止其往下传递。

(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子 View 没有消费事件,事件会反向往上传递,这时父 View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到 Activity 的 onTouchEvent()函数。

(4) 如果 View 没有对 ACTION_DOWN 进行消费,之后的其他事件不会传递过来。

(5) OnTouchListener 优先于 onTouchEvent()对事件进行消费。
上面的消费即表示相应函数返回值为 true。

Android中的事件分发机制总结的更多相关文章

  1. Android中的事件分发机制

    Android中的事件分发机制 作者:丁明祥 邮箱:2780087178@qq.com 这篇文章这周之内尽量写完 参考资料: Android事件分发机制完全解析,带你从源码的角度彻底理解(上) And ...

  2. 浅谈Android中的事件分发机制

    View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...

  3. 安卓中的事件分发机制之View控件

    前言:Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent e ...

  4. 【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher

    一.简介 最近马三换了一家大公司工作,公司制度规范了一些,因此平时的业余时间多了不少.但是人却懒了下来,最近这一个月都没怎么研究新技术,博客写得也是拖拖拉拉,周六周天就躺尸在家看帖子.看小说,要么就是 ...

  5. Android view 的事件分发机制

    1 事件的传递顺序是 Activity -> Window -> 顶层View touch 事件产生后,最先由 activity 的 dispatchTouchEvent 处理 /** * ...

  6. Android的Touch事件分发机制简单探析

    前言 Android中关于触摸事件的分发传递是一个很值得研究的东西.曾不见你引入了一个ListView的滑动功能,ListView就不听你手指的指唤来滚动了:也不知道为啥Button设置了onClic ...

  7. Android View的事件分发机制

    准备了一阵子,一直想写一篇事件分发的文章总结一下.这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等.这些子View的外层还有ViewGroup ...

  8. Android View的事件分发机制和滑动冲突解决方案

    这篇文章会先讲Android中View的事件分发机制,然后再介绍Android滑动冲突的形成原因并给出解决方案.因水平有限,讲的不会太过深入,只希望各位看了之后对事件分发机制的流程有个大概的概念,并且 ...

  9. Android程序员事件分发机制学习笔记

    通过问题来学习一个东西是很好的方法.学习Android中View的事件体系,我也通过给自己提问题,在解决问题的同时也就知道了其中原理. 首先来几个问题起步: 什么是事件?什么是事件分发机制? 在我们通 ...

随机推荐

  1. 使用SharePoint 2010的母版页

    转:http://tanyanbo2.blog.163.com/blog/static/97339159201111591458902/ SharePoint 2010母版页所用的还是ASP.NET ...

  2. codeforces 671B Robin Hood 二分

    题意:有n个人,每个人a[i]个物品,进行k次操作,每次都从最富有的人手里拿走一个物品给最穷的人 问k次操作以后,物品最多的人和物品最少的人相差几个物品 分析:如果次数足够多的话,最后的肯定在平均值上 ...

  3. eclipse+xdebug

    root@leeyoung-Satellite-M300:/etc/apache2/sites-available# nano 000-default.conf <IfModule dir_mo ...

  4. 【原】Redis分区

    Redis高级篇 分区 为什么分区? Redis中的分区主要有两个目的: 允许用多台机器的内存存放更大的数据集.如果没有分区,那么你只能存放单台机器内存的最大值的数据集. 允许用多核和多台机器提高计算 ...

  5. algorithm@ find kth smallest element in two sorted arrays (O(log n time)

    The trivial way, O(m + n): Merge both arrays and the k-th smallest element could be accessed directl ...

  6. 关于mac 80端口问题

    使用 maven启动 jettry时 ,jetty使用的是80端口 ,但是 mac 在1024以下的端口似乎是不让随便使用的. 在网上查了好多方式,其中的一种说是做端口转发,其实也就是把80转换成别的 ...

  7. iPhone开发教程之retain/copy/assign/setter/getter

    assign: 简单赋值,不更改索引计数 copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 1. 接触过C,那么 ...

  8. 转载LINQ TO Entity 在数据库发生更改时更新实体数据模型 .edmx 文件

    转载原出处:http://blog.csdn.net/litao2/article/details/8629335 在“模型浏览器”中,右击 .edmx 文件,然后选择“从数据库更新模型”. 模型更新 ...

  9. Packetbeat协议扩展开发教程(2)

    原文链接:http://elasticsearch.cn/article/53 书接上回:http://elasticsearch.cn/article/48 我们打开Packetbeat项目,看看里 ...

  10. CentOS6 配置

    1.CentOS6 Minimal 安装的情况下,默认网卡不启动,并且默认设置了依赖 NetworkManager 的选项.又因为 Minimal 安装并不会安装系统默认提供的网络管理工具  Netw ...