Android 触摸事件 点击事件的分发机制 详解二

现在我们来看看 事件分发的流程。view group 怎么传递给view的。

首先自定义一个layout

 1 package com.example.testtouch;
 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 MyLayout extends LinearLayout {
10
11     public MyLayout(Context context) {
12         super(context);
13         // TODO Auto-generated constructor stub
14     }
15
16     public MyLayout(Context context, AttributeSet attrs) {
17         super(context, attrs);
18         // TODO Auto-generated constructor stub
19     }
20
21     @Override
22     public boolean onInterceptTouchEvent(MotionEvent ev) {
23         // TODO Auto-generated method stub
24
25         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
26             Log.v("test", "MyLayout onInterceptTouchEvent==DOWN");
27         }
28         if (ev.getAction() == MotionEvent.ACTION_UP) {
29             Log.v("test", "MyLayout onInterceptTouchEvent==UP");
30         }
31         Log.v("test",
32                 "MyLayout onInterceptTouchEvent 默认值=="
33                         + super.onInterceptTouchEvent(ev));
34
35         return super.onInterceptTouchEvent(ev);
36     }
37
38     @Override
39     public boolean onTouchEvent(MotionEvent event) {
40         if (event.getAction() == MotionEvent.ACTION_DOWN) {
41             Log.v("test", "MyLayout onTouchEvent==DOWN");
42         }
43         if (event.getAction() == MotionEvent.ACTION_UP) {
44             Log.v("test", "MyLayout onTouchEvent==UP");
45         }
46         Log.v("test", "MyLayout onTouchEvent 默认值==" + super.onTouchEvent(event));
47         return super.onTouchEvent(event);
48     }
49
50 }

然后定义一个view

 1 package com.example.testtouch;
 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     public MyTextView(Context context) {
12         super(context);
13         // TODO Auto-generated constructor stub
14     }
15
16     public MyTextView(Context context, AttributeSet attrs) {
17         super(context, attrs);
18         // TODO Auto-generated constructor stub
19     }
20
21     @Override
22     public boolean onTouchEvent(MotionEvent event) {
23         if (event.getAction() == MotionEvent.ACTION_DOWN) {
24             Log.v("test", "MyTextView onTouchEvent down事件");
25         }
26         if (event.getAction() == MotionEvent.ACTION_UP) {
27             Log.v("test", "MyTextView onTouchEvent up 事件");
28         }
29
30         Log.v("test",
31                 "MyTextView onTouchEvent==默认值==" + super.onTouchEvent(event));
32         return super.onTouchEvent(event);
33     }
34
35 }

然后 我们来run 一下 这个界面。

并且点击一下 这个自定义的view 看看会发生什么。

10-31 08:53:44.620: V/test(7702): MyLayout onInterceptTouchEvent==DOWN
10-31 08:53:44.649: V/test(7702): MyLayout onInterceptTouchEvent 默认值==false
10-31 08:53:44.649: V/test(7702): MyTextView onTouchEvent down事件
10-31 08:53:44.649: V/test(7702): MyTextView onTouchEvent==默认值==false
10-31 08:53:44.649: V/test(7702): MyLayout onTouchEvent==DOWN
10-31 08:53:44.649: V/test(7702): MyLayout onTouchEvent 默认值==false

可以看出来 我们点击这个view的时候  是上层的layout先捕捉到了这个事件。 并且layout的 onInterceptTouchEvent 返回值 默认的是false。

然后把这个点击事件 传递给了 子空间 也就是这个view。 这个子view 也补获到了这个事件。并且子view的事件 捕捉到了以后 又抛给了 layout的ontouchevent 这个函数。

从而 layout的onTouchEvent也捕获到了这个action事件。

当然有人要问 一个点击事件 有down肯定有up,哪up事件 怎么没捕获到? 正如前面一篇博客讲的,onTouchEvent  这个函数。对于aciton down事件来说 如果返回false

后面的事件都捕获不到了。

我们可以验证一下  把 mytextview的 onTouchEvent返回值改写成固定的true。

看看会发生什么。

 1 package com.example.testtouch;
 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     public MyTextView(Context context) {
12         super(context);
13         // TODO Auto-generated constructor stub
14     }
15
16     public MyTextView(Context context, AttributeSet attrs) {
17         super(context, attrs);
18         // TODO Auto-generated constructor stub
19     }
20
21     @Override
22     public boolean onTouchEvent(MotionEvent event) {
23         if (event.getAction() == MotionEvent.ACTION_DOWN) {
24             Log.v("test", "MyTextView onTouchEvent down事件");
25         }
26         if (event.getAction() == MotionEvent.ACTION_UP) {
27             Log.v("test", "MyTextView onTouchEvent up 事件");
28         }
29
30         Log.v("test",
31                 "MyTextView onTouchEvent==默认值==" + super.onTouchEvent(event));
32         return true;
33     }
34
35 }

10-31 08:59:35.489: V/test(8740): MyLayout onInterceptTouchEvent==DOWN
10-31 08:59:35.489: V/test(8740): MyLayout onInterceptTouchEvent 默认值==false
10-31 08:59:35.489: V/test(8740): MyTextView onTouchEvent down事件
10-31 08:59:35.489: V/test(8740): MyTextView onTouchEvent==默认值==false
10-31 08:59:35.579: V/test(8740): MyLayout onInterceptTouchEvent==UP
10-31 08:59:35.579: V/test(8740): MyLayout onInterceptTouchEvent 默认值==false
10-31 08:59:35.579: V/test(8740): MyTextView onTouchEvent up 事件
10-31 08:59:35.579: V/test(8740): MyTextView onTouchEvent==默认值==false

可以看出来 对于 mytextview 来说 他的 up事件 也捕获到了 但是layout的 onTouchEvent 并没有捕获到up事件,甚至他的onTouchEvent都没有执行!!!!!!!

然后我们再把mylayout的onInterceptTouchEvent 的返回值改写成true 看看会有什么结果

 1 package com.example.testtouch;
 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 MyLayout extends LinearLayout {
10
11     public MyLayout(Context context) {
12         super(context);
13         // TODO Auto-generated constructor stub
14     }
15
16     public MyLayout(Context context, AttributeSet attrs) {
17         super(context, attrs);
18         // TODO Auto-generated constructor stub
19     }
20
21     @Override
22     public boolean onInterceptTouchEvent(MotionEvent ev) {
23         // TODO Auto-generated method stub
24
25         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
26             Log.v("test", "MyLayout onInterceptTouchEvent==DOWN");
27         }
28         if (ev.getAction() == MotionEvent.ACTION_UP) {
29             Log.v("test", "MyLayout onInterceptTouchEvent==UP");
30         }
31         Log.v("test",
32                 "MyLayout onInterceptTouchEvent 默认值=="
33                         + super.onInterceptTouchEvent(ev));
34
35         return true;
36     }
37
38     @Override
39     public boolean onTouchEvent(MotionEvent event) {
40         if (event.getAction() == MotionEvent.ACTION_DOWN) {
41             Log.v("test", "MyLayout onTouchEvent==DOWN");
42         }
43         if (event.getAction() == MotionEvent.ACTION_UP) {
44             Log.v("test", "MyLayout onTouchEvent==UP");
45         }
46         Log.v("test", "MyLayout onTouchEvent 默认值==" + super.onTouchEvent(event));
47         return super.onTouchEvent(event);
48     }
49
50 }

10-31 09:06:20.649: V/test(9635): MyLayout onInterceptTouchEvent==DOWN
10-31 09:06:20.659: V/test(9635): MyLayout onInterceptTouchEvent 默认值==false
10-31 09:06:20.659: V/test(9635): MyLayout onTouchEvent==DOWN
10-31 09:06:20.659: V/test(9635): MyLayout onTouchEvent 默认值==false

发现 子view mytextview的事件根本捕获不到了!!!!!!!!!!!!被拦截在layout这一层了。

把layout的ontouchevent 改写成true 看看是否能捕获到up事件。

 1 package com.example.testtouch;
 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 MyLayout extends LinearLayout {
10
11     public MyLayout(Context context) {
12         super(context);
13         // TODO Auto-generated constructor stub
14     }
15
16     public MyLayout(Context context, AttributeSet attrs) {
17         super(context, attrs);
18         // TODO Auto-generated constructor stub
19     }
20
21     @Override
22     public boolean onInterceptTouchEvent(MotionEvent ev) {
23         // TODO Auto-generated method stub
24
25         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
26             Log.v("test", "MyLayout onInterceptTouchEvent==DOWN");
27         }
28         if (ev.getAction() == MotionEvent.ACTION_UP) {
29             Log.v("test", "MyLayout onInterceptTouchEvent==UP");
30         }
31         Log.v("test",
32                 "MyLayout onInterceptTouchEvent 默认值=="
33                         + super.onInterceptTouchEvent(ev));
34
35         return true;
36     }
37
38     @Override
39     public boolean onTouchEvent(MotionEvent event) {
40         if (event.getAction() == MotionEvent.ACTION_DOWN) {
41             Log.v("test", "MyLayout onTouchEvent==DOWN");
42         }
43         if (event.getAction() == MotionEvent.ACTION_UP) {
44             Log.v("test", "MyLayout onTouchEvent==UP");
45         }
46         Log.v("test", "MyLayout onTouchEvent 默认值==" + super.onTouchEvent(event));
47         return true;
48     }
49
50 }

结果发现是可以捕获到的

10-31 09:07:56.620: V/test(9913): MyLayout onInterceptTouchEvent==DOWN
10-31 09:07:56.620: V/test(9913): MyLayout onInterceptTouchEvent 默认值==false
10-31 09:07:56.620: V/test(9913): MyLayout onTouchEvent==DOWN
10-31 09:07:56.620: V/test(9913): MyLayout onTouchEvent 默认值==false
10-31 09:07:56.712: V/test(9913): MyLayout onTouchEvent==UP
10-31 09:07:56.712: V/test(9913): MyLayout onTouchEvent 默认值==false

ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.如果返回true 那上层layout就会拦截touch事件

ViewGroup里的onTouchEvent默认值是false。

 

时间: 2024-10-09 05:01:33

Android 触摸事件 点击事件的分发机制 详解二的相关文章

Android事件分发机制详解(1)----探究View的事件分发

探究View的事件分发 在Activity中,只有一个按钮,注册一个点击事件 [java] view plaincopy button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d("TAG", "onClick execute"); } }); 如果在需要一个触摸事件 [java] view plaincopy button.setO

Android事件分发机制详解(2)----分析ViewGruop的事件分发

首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接父类. 但ViewGroup也是一个View,只不过比起View,它可以包含子View和定义布局参数的功能. 现在,通过一个Demo演示Android中ViewGroup的事件分发机制. 首先我们来自定义一个布局,命名为MyLayout,继承自LinearLayout,如下 所示: public c

Cocos2d-X研究之v3.x 事件分发机制详解

事件分发机制 新事件分发机制:在2.x 版本事件处理时,将要触发的事件交给代理(delegate)处理,再通过实现代理里面的onTouchBegan等方法接收事件,最后完成事件的响应.而在新的事件分发机制中,只需通过创建一个事件监听器-用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher,所有事件监听器由这个分发器统一管理,即可完成事件响应.请参考更多3.0资料... 事件监听器有以下几种: 触摸事件 (EventListenerTouch) 键盘响应事件 (Event

android 事件分发机制详解(OnTouchListener,OnClick)

昨天做东西做到触摸事件冲突,以前也经常碰到事件冲突,想到要研究一下Android的事件冲突机制,于是从昨天开始到今天整整一天时间都要了解这方面的知识,这才懂了安卓的触摸和点击事件的机制.探究如下: 首先重写三个View布局,用来做测试: package com.example.yzj.android_8_10; import android.content.Context; import android.util.AttributeSet; import android.util.Log; im

Android 触摸事件 点击事件的分发机制 详解

最近发现团队里有些员工在做一些自定义控件的时候感觉比较吃力.尤其是做触摸事件这种东西的时候.很多人对机制并不理解.因为百度出来的东西都太理论化了.确实不好理解. 今天带大家坐几个小demo.帮助理解一下. 先从简单的view 的事件分发机制开始解释. 我们首先自定义一个工程 package com.example.testtouch; import android.app.Activity; import android.os.Bundle; import android.util.Log; i

Android 触摸事件 点击事件的分发机制 详解三---责任链模式

前面两节  我们讲述了 android 点击事件的分发流程.其实大家可以细细体会一下,这个分发的过程 始终是从顶层到下层.一层一层的按照顺序进行. 当然了,传到哪一层停止,我们可以通过重写某些方法来完成. 这个地方 android的开发人员很好的利用了 责任链模式来完成这边代码的编写. 下面我们就来讲一下 责任链模式到底是什么.以及如何运用. 大家知道 一个软件公司的基本架构就是 程序员----leader---project manager---boss 这种基础架构. 我们一般都会有team

Android事件分发机制详解:史上最全面、最易懂

前言 Android事件分发机制是每个Android开发者必须了解的基础知识 网上有大量关于Android事件分发机制的文章,但存在一些问题:内容不全.思路不清晰.无源码分析.简单问题复杂化等等 今天,我将全面总结Android的事件分发机制,我能保证这是市面上的最全面.最清晰.最易懂的 本文秉着"结论先行.详细分析在后"的原则,即先让大家感性认识,再通过理性分析从而理解问题: 所以,请各位读者先记住结论,再往下继续看分析: 文章较长,阅读需要较长时间,建议收藏等充足时间再进行阅读 目

Android事件分发机制详解

我们通过一个示例来分析Touch事件的分发过程. 示例: 布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id=&

Android 事件分发机制详解

更多内容请参照我的个人站点: http://stackvoid.com/ 网上很多关于Android事件分发机制的解释,大多数描述的都不够清晰,没有吧来龙去脉搞清楚,本文将带你从Touch事件产生到Touch事件被消费这一全过程作全面的剖析. 产生Touch事件 这部分牵扯到硬件和Linux内核部分:我们简单讲述一下这部分内容,如果有兴趣的话可以参考这篇文章. 传递Touch事件 触摸事件是由Linux内核的一个Input子系统来管理的(InputManager),Linux子系统会在/dev/