[学习总结]4、Android的ViewGroup中事件的传递机制(一)
本文主要针对dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent三个方法,通过简单的例子来简单的介绍下。
根据字面意思的理解,dispatchTouchEvent分发触摸事件,onInterceptTouchEvent拦截触摸事件,onTouchEvent触摸事件。正如它们各自的字面意思,下面简单的列出各自的作用和用法。
1、dispatchTouchEvent作用:决定事件是否由onInterceptTouchEvent来拦截处理。
- 返回super.dispatchTouchEvent时,由onInterceptTouchEvent来决定事件的流向
- 返回false时,不会继续分发事件,自己内部只处理了ACTION_DOWN
- 返回true时,不会继续分发事件,自己内部处理了所有事件(ACTION_DOWN,ACTION_MOVE,ACTION_UP)
2、onInterceptTouchEvent作用:拦截事件,用来决定事件是否传向子View
- 返回true时,拦截后交给自己的onTouchEvent处理
- 返回false时,拦截后交给子View来处理
3、onTouchEvent作用:事件最终到达这个方法
- 返回true时,内部处理所有的事件
- 返回false时,事件会向上传递,由onToucEvent来接受,如果最上面View中的onTouchEvent也返回false的话,那么事件就会消失。
- down事件首先会传递到onInterceptTouchEvent()方法
- 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理
- 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。
- 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理
- 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。
这是摘自网络:
More:
1. 一个事件必然从ACTION_DOWN开始,所以当某一个控件处理了一个ACTION_DOWN事件,可以理解直到下一个ACTION_DOWN之前所有的触摸事件都应当由该控件(target)进行处理。
2. 对于各种listener,显然是由android系统进行处理的。所以Super.onTouchEvent()应当放在子类的该函数的第一行,可以优先保证系统的方法不会被自定义的操作截取而导致没有机会执行。
3. 牢记一个原则,所有的touch事件都是从父容器开始向下传递的,呈U字形
(1) 父容器(类型为 <? Extends ViewGroup>) onInterceptTouchEvent接收到事件,如果return false,转步骤(2),否则转 步骤(3)
(2) 父容器在该位置(ACTION_DOWN发生的位置)存在子控件,如果子控件类型为
<? Extends ViewGroup>,此时该子控件成为父容器,转步骤(1),如果子控件为普通view,即 不是viewgroup的子类,使用子控件转步骤(3),如果不存在子控件,使用父容器转步骤(3)
(3) 该touch事件交给该控件的onTouchEvent进行响应,如果return false,当其存在父容器时,事件传递给父容器,转步骤(3)。当不存在父容器时,该事件被丢弃。如果return true,表示事件被消费了,此touch事件终止。
关于事件传递解释的更好的文章在这里。
下面结合具体的例子来讲解,首先是容器类MyLinearLayout继承自LinearLayout,子View类MyTextView继承自TextView。
MyLinearLayout类:
1 package com.example.time;
2
3 import android.content.Context;
4 import android.util.AttributeSet;
5 import android.util.Log;
6 import android.view.MotionEvent;
7 import android.widget.LinearLayout;
8
9 public class MyLinearLayout extends LinearLayout {
10
11 private String TAB = "MyLinearLayout";
12
13 public MyLinearLayout(Context context, AttributeSet attrs) {
14 super(context, attrs);
15 }
16
17 public MyLinearLayout(Context context) {
18 super(context);
19 }
20
21 @Override
22 public boolean dispatchTouchEvent(MotionEvent ev) {
23 switch(ev.getAction()) {
24 case MotionEvent.ACTION_DOWN:
25 Log.d(TAB, "dispatchTouchEvent action:ACTION_DOWN");
26 break;
27 case MotionEvent.ACTION_UP:
28 Log.d(TAB, "dispatchTouchEvent action:ACTION_UP");
29 break;
30 }
31 return super.dispatchTouchEvent(ev);
32 }
33
34 @Override
35 public boolean onInterceptTouchEvent(MotionEvent ev) {
36 //true表示拦截后交给自己的onTouchEvent处理,false表示传递给子View
37 switch(ev.getAction()) {
38 case MotionEvent.ACTION_DOWN:
39 Log.d(TAB, "onInterceptTouchEvent action:ACTION_DOWN");
40 break;
41 case MotionEvent.ACTION_UP:
42 Log.d(TAB, "onInterceptTouchEvent action:ACTION_UP");
43 break;
44 }
45 return false;
46 }
47
48 @Override
49 public boolean onTouchEvent(MotionEvent event) {
50 switch(event.getAction()) {
51 case MotionEvent.ACTION_DOWN:
52 Log.d(TAB, "---onTouchEvent action:ACTION_DOWN");
53 break;
54 case MotionEvent.ACTION_UP:
55 Log.d(TAB, "---onTouchEvent action:ACTION_UP");
56 break;
57 }
58 return false;
59 }
60 }
MyTextView类:
1 package com.example.time;
2
3 import android.content.Context;
4 import android.util.AttributeSet;
5 import android.util.Log;
6 import android.view.MotionEvent;
7 import android.widget.TextView;
8
9 public class MyTextView extends TextView {
10
11 private String TAB = "MyTextView";
12
13 public MyTextView(Context context, AttributeSet attrs, int defStyle) {
14 super(context, attrs, defStyle);
15 }
16
17 public MyTextView(Context context, AttributeSet attrs) {
18 super(context, attrs);
19 }
20
21 public MyTextView(Context context) {
22 super(context);
23 }
24
25 @Override
26 public boolean dispatchTouchEvent(MotionEvent event) {
27 switch(event.getAction()) {
28 case MotionEvent.ACTION_DOWN:
29 Log.d(TAB, "dispatchTouchEvent action:ACTION_DOWN");
30 break;
31 case MotionEvent.ACTION_UP:
32 Log.d(TAB, "dispatchTouchEvent action:ACTION_UP");
33 break;
34 }
35 return super.dispatchTouchEvent(event);
36 }
37
38 @Override
39 public boolean onTouchEvent(MotionEvent event) {
40 switch(event.getAction()) {
41 case MotionEvent.ACTION_DOWN:
42 Log.d(TAB, "---onTouchEvent action:ACTION_DOWN");
43 break;
44 case MotionEvent.ACTION_UP:
45 Log.d(TAB, "---onTouchEvent action:ACTION_UP");
46 break;
47 }
48 return false;
49 }
50
51 }
布局文件activity_main.xml
1 <com.example.time.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:id="@+id/testview"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:gravity="center" >
6 <com.example.time.MyTextView
7 android:layout_width="200dip"
8 android:layout_height="200dip"
9 android:text="@string/hello_world"
10 android:textSize="50sp" />
11 </com.example.time.MyLinearLayout>
为了更清晰的理解事件的分发处理机制,最好自己将上面代码运行一下,主要更改下MyLinearLayout中的onInterceptTouchEvent的返回值(true或false),还有两个类中的onTouchEvent的返回值,来观察logcat中的打印结果,基本上和上面总结出来的一致。
记住一点:true就是自己内部消化掉所有事件,false就是继续传递事件。
[学习总结]5、Android的ViewGroup中事件的传递机制(二)
[学习总结]4、Android的ViewGroup中事件的传递机制(一)的更多相关文章
- [学习总结]5、Android的ViewGroup中事件的传递机制(二)
下面是第一篇的连接 Android的ViewGroup中事件的传递机制(一) 关于onInterceptTouchEvent和onTouchEvent的详细解释. 1 public class Mai ...
- Android: 详解触摸事件如何传递
当视图的层次结构比较复杂的时候,触摸事件的响应流程也变得复杂. 举例来说,你也许有一天想要制作一个手势极其复杂的 Activity 来折磨你的用户,你经过简单思索,认为其中应该包含一个 PageVie ...
- Android与javascript中事件分发机制的简单比较
在前面两篇博客中,我们讨论了Android中的事件分发的相关内容,那么在本篇博客当中,我们就简单探讨一下html或javascript中的事件分发机制,并进行简单的对比. 在前端中,对事件进行绑定有三 ...
- android的事件分发传递机制
事件的分发与传递最重要的三个处理方法是 dispatchTouchEvent onInterceptTouchEvent onTouchEvent 综合来说事件的 传递是由外层向里层传递,而处理是从里 ...
- iOS中事件的传递和响应者链条
在iOS 开发中,常见的事件有三种类型,分别是: (1)触摸事件:平常手指在屏幕上滑动,产生的事件都是触摸事件 (2)加速计事件:微信的摇一摇就是典型的加速计事件 (3)远程控制事件:耳机控制歌曲上一 ...
- Android初级教程:单击事件的传递机制初谈
以上仅是小试牛刀,后续有很多事件传递机制,继续探讨.
- Android系统中长按事件的实现机制解析
在Android的触摸消息中,已经实现了三种监测,它们分别是 1)pre-pressed:对应的语义是用户轻触(tap)了屏幕 2)pressed:对应的语义是用户点击(press)了屏幕 3)lon ...
- Android笔记——Activity中的数据传递案例(用户注冊)
1.创建程序activity_main: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/andro ...
- 【Android】Intent中使用Extra传递数据
传值方法一 Intent intent = new Intent(); Bundle bundle = new Bundle(); //该类用作携带数据 bundle.putString(" ...
随机推荐
- 创建双向 CA x509 验证证书 kube-apiserver
1. 设置 kube-apiserver 的 CA 证书相关的文件和启动参数 使用 OpenSSL 工具在 Master 服务器上创建 CA 证书和私钥相关的文件: # openssl genrsa ...
- Java测试开发--lambda函数式编程(六)
1.Lambda 表达式,是jdk1.8特性,接口里只有一个方法. 举例说明 // ()参数列表 ->连接符 {方法体} 经常在匿名对象 testPerson(()->{System.ou ...
- 『学了就忘』Linux基础命令 — 37、Linux中挂载操作的相关命令
目录 1.mount命令介绍 (1)mount命令说明 (2)mount命令格式 2.mount命令示例 3.mount -a命令说明 4.-o特殊选项说明 5.exec/noexec选项说明 挂载就 ...
- 5.0jemter(英文版)录制脚本,进行压力测试
压力测试的目的:找到瓶颈.优化速率 1.jemter,Test Plan-->>Add-->>Threds(users)-->>Thred Group创建线程组 2 ...
- dedecms被挂马排毒的过程
又经历了一次dedecms被挂马排毒的过程,排毒过程在这里跟大家分享一下. 挂马之后,网站的表现形式: 直接访问网站没有任何问题,从百度搜索的关键词访问网站,就跳转到另外一个网站. 根据我原来的排毒经 ...
- 菜鸡的Java笔记 第三十三 - java 泛型
泛型 GenericParadigm 1.泛型的产生动机 2.泛型的使用以及通配符 3.泛型方法的使用 JDK1.5 后的三大主 ...
- 第三章 sql 的约束
1.0 约束分类 约束类型: 主键 默认值 唯一 外键 非空 关键字: PRIMARY KEY DEFAULT UNIQUE FOREIGN NOT NULL 2.0 建立含约束的表 3.0 主 ...
- SQL中单引号和双引号
比如说: String sql = "select * from clients where logname='" + name + "'and password='&q ...
- c语言1左移32位(1<<32)是多少,左移-1位呢
C语言中 << 是逻辑移位,不是循环移位.1 左移 32 位后为 0,左移 -1 位实际是左移 255 位(互补),当然也是0.这种问题可以写一段小程序,单步执行,看一下每一步的结果.先说 ...
- [bzoj5510]唱跳rap和篮球
显然答案可以理解为有(不是仅有)0对情况-1对情况+2对情况-- 考虑这个怎么计算,先计算这t对情况的位置,有c(n-3t,t)种情况(可以理解为将这4个点缩为1个,然后再从中选t个位置),然后相当于 ...