码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2014-10-31 18:47:56      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:android   style   blog   io   color   ar   sp   strong   div   

现在我们来看看 事件分发的流程。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。

 

 

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

标签:android   style   blog   io   color   ar   sp   strong   div   

原文地址:http://www.cnblogs.com/punkisnotdead/p/4065543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!