热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

现在我们来看看事件分发的流程。viewgroup怎么传递给view的。首先自定义一个layout1packagecom.example.testtouch;23importandr

现在我们来看看 事件分发的流程。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 触摸事件 点击事件的分发机制 详解二


推荐阅读
  • 自定义RecyclerView添加EmptyView
    你知道RecyclerView里没有Em ... [详细]
  • iOS之富文本
    之前做项目时遇到一个问题:使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结 ... [详细]
  • Xib九宫格应用管理使用xib封装一个自定义view的步骤1新建一个继承UIView的自定义view,假设类名叫做(AppView)2新建一个AppView.xib文件来描述 ... [详细]
  • 我们需要监听ScroView的滑动情况,比如滑动了多少距离,是否滑到布局的顶部或者底部。可惜的是SDK并没有相应的方法,不过倒是提供了一个protectedvoidonScrollChang ... [详细]
  • packagetest;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOE ... [详细]
  • AsyncDisplayKit2.0教程(下)
    AsyncDisplayKit2.0Tutorial:AutomaticLayout原文:AsyncDisplayKit2.0Tutorial:Automatic ... [详细]
  • 调用:视图调用:1@Html.DropDownListFor(tt.HrEmpGuid,ViewData[Emp] as SelectList, new {@class   ... [详细]
  • 本文分析和介绍了GLo ... [详细]
  • 2019.4.14第1001题:SumProblemProblemDescriptionHey,welcometoHDOJ(HangzhouDianziUniversityOnli ... [详细]
  • 抓取百万知乎用户设计之实体设计
    一.实体的关系实体是根据返回的Json数据来设计的教育经历方面用户可以有很多教育经理,USER和education是一对多的关系,一个education对应一个education一 ... [详细]
  • 作业迁移
    背景:数据库服务器更换,1、数据库迁移(BACKUPRESTORE);2、数据库登录名用户迁移(注意孤立用户);3、作业迁移数据库迁移,备份数据库、拷贝备份文件到新服务器,还原数据 ... [详细]
  • ARToolKitunity
    ARToolKit为开源的AR库,相对于高通和easyAr有几点特点:1)开源2)识别项目可以动态添加(详细在后)3)识别文件可以本地生成4)目前只能识别图片(目前为.jpg格式) ... [详细]
  • ASP.NET Core WebAPI 开发新建WebAPI项目  转
    转 http:www.cnblogs.comlinezerop5497472.htmlASP.NETCoreWebAPI开发-新建WebAPI项目ASP.NETCoreWebAPI ... [详细]
  • Adapter相当于C(Controller,控制器),listView相当于V(View,视图)用于显示数据为ListView提供数据的List,数组或数据库相当于MVC模式中的 ... [详细]
  • 先看看效果是不是自己想要的吧item及item内部控件点击事件不懂的可以先点击查看 ... [详细]
author-avatar
张怡如秋岳
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有