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. HOG:从理论到OpenCV实践

    (转载请注明出处:http://blog.csdn.net/zhazhiqiang/ 未经允许请勿用于商业用途) 一.理论 1.HOG特征描述子的定义:     locally normalised ...

  2. 机器学习总结之逻辑回归Logistic Regression

    机器学习总结之逻辑回归Logistic Regression 逻辑回归logistic regression,虽然名字是回归,但是实际上它是处理分类问题的算法.简单的说回归问题和分类问题如下: 回归问 ...

  3. mysql日期加减问题

    有一个date列,我想修改下,让该列里每个日期都加上7天,怎么写代码?  update [表名] set date=date_add(date, interval 7 day); SELECT * f ...

  4. 【Hadoop代码笔记】Hadoop作业提交之客户端作业提交

    1.      概要描述仅仅描述向Hadoop提交作业的第一步,即调用Jobclient的submitJob方法,向Hadoop提交作业. 2.      详细描述Jobclient使用内置的JobS ...

  5. Go语言 字符串

    在所有编程语言中都涉及到大量的字符串操作,可见熟悉对字符串的操作是何等重要. Go中的字符串和C#中的一样(java也是),字符串内容在初始化后不可修改. 需要注意的是在Go中字符串是有UTF-8编码 ...

  6. unigui下载文件

    lblProduct.Caption := '<a href="files\1.t" target=new>要下载的文件名</a>';

  7. mssql游标demo

    declare @billIds varchar(400) declare @billId varchar(40) DECLARE c1 CURSOR FOR select top 5 SaleNo ...

  8. 4.22 注入js需要加 addjavascriptinterface

    由于项目需要,再次使用到了android的webview,webview要加载的页面是html5的页面: 需要有点击webview中的控件的交互,所以需要在android应用中注入一个js对象: 通过 ...

  9. PowerDesigner 正向工程 和 逆向工程 说明

    PowerDesigner 正向工程 和 逆向工程 说明 database数据库脚本oraclegenerationsql   目录(?)[+]   一. 正向工程与逆向工程说明 在前面几篇里介绍了几 ...

  10. A Mathematician‘s Survival Guide Graduate School and Early Career Development

    推荐大家一本书尤其是即将读研究生或者研一研二的学生:                                                     A Mathematician‘s  Su ...