Android 编程下Touch 事件的分发和消费机制和OnTouchListener,OnClickListener和OnLongClickListener的关系
1.事件分发:public boolean dispatchTouchEvent(MotionEvent ev)
Touch 事件发生时 Activity 的 dispatchTouchEvent(MotionEvent ev) 方法会以隧道方式(从根元素依次往下传递直到最内层子元素或在中间某一元素中由于某一条件停止传递)将事件传递给最外层 View 的 dispatchTouchEvent(MotionEvent ev) 方法,并由该 View 的 dispatchTouchEvent(MotionEvent ev) 方法对事件进行分发。dispatchTouchEvent 的事件分发逻辑如下:
如果 return true,事件会分发给当前 View 并由 dispatchTouchEvent 方法进行消费,同时事件会停止向下传递;
如果 return false,事件分发分为两种情况:
如果当前 View 获取的事件直接来自 Activity,则会将事件返回给 Activity 的 onTouchEvent 进行消费;
如果当前 View 获取的事件来自外层父控件,则会将事件返回给父 View 的 onTouchEvent 进行消费。
如果返回系统默认的 super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。
2.事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)
在当前 View 的 dispatchTouchEvent(MotionEvent ev) 方法返回系统默认的 super.dispatchTouchEvent(ev) 情况下,事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。onInterceptTouchEvent 的事件拦截逻辑如下:
如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
如果 onInterceptTouchEvent 返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发,如果当前事件没有点击在子View上而是在当前View其他空白区域,则发给当前 View 的 onTouchEvent 进行处理;
如果 onInterceptTouchEvent 返回super.onInterceptTouchEvent(ev)和返回false的处理逻辑一样。
3.事件响应:public boolean onTouchEvent(MotionEvent ev)
在 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev) 并且 onInterceptTouchEvent 返回 true 或者由子View 的 onTouchEvent返回false的情况下 onTouchEvent 会被调用。onTouchEvent 的事件响应逻辑如下:
如果事件传递到当前 View 的 onTouchEvent 方法,而该方法返回了 false,那么这个事件会从当前 View 向上传递,并且都是由上层 View 的 onTouchEvent 来接收,如果传递到上面的 onTouchEvent 也返回 false,这个事件就会“消失”,而且接收不到下一次事件。
如果返回了 true 则会接收并消费该事件,如果没有其他特殊情况,下次事件不经过onInterceptTouchEvent(MotionEvent ev)。
如果返回 super.onTouchEvent(ev) 默认处理事件的逻辑和返回 false 时相同。
OnTouchListener,OnClickListener和OnLongClickListener的关系
在OnTouchListener事件里有MotionEvent.ACTION_DOWN,MotionEvent.ACTION_UP和MotionEvent.ACTION_MOVE三个事件,我们在这里只讨论MotionEvent.ACTION_DOWN,MotionEvent.ACTION_UP,与MOVE无关。在下面的文章中我们简称MotionEvent.ACTION_DOWN为TouchDown,简称MotionEvent.ACTION_UP为TouchUp。我们还知道Android有消化事件这个概念,在setOnTouchListener函数中如果是TouchDown我们返回true,在下文中我们称消化了TouchDown,返回false则没消化,TouchUp同理。
下面我们说明关系和证明(在用程序证明时每次运行都以 程序----操作----结果的顺序给出)。
1)OnTouchListener和OnClickListener的关系
关系:产生OnClick事件的条件(充要条件)是;TouchDown和TouchUp事件都没有被消化。事件处理的过程是:先处理TouchDown,之后处理TouchUp,如果这两个事件都没被消化,则处理OnClick事件。
程序结果:由于这个关系比较简单就不上图了。程序分4种情况分别为:
a)程序:消化TouchDown,不消化TouchUp------操作:单击按钮------结果:不产生OnClick事件
b)程序:不消化TouchDown,消化TouchUp------操作:单击按钮------结果:不产生OnClick事件
c)程序:消化TouchDown,消化TouchUp------操作:单击按钮------结果:不产生OnClick事件
d)程序:不消化TouchDown,不消化TouchUp----操作:单击按钮----结果:产生OnClick事件
2)OnTouchListener和OnLongClickListener的关系
关系:产生OnLongClick事件的条件(充要条件)是;在产生TouchDown事件,并且该TouchDown没有被消化,之后500毫秒内没有响应到TouchUp,则产生OnLongClick事件。
程序结果:对运行情况按TouchDown是否被消化,TouchUp是否被消化,我的操作是长按还是短按可以分为8种运行情况,在这里就不一一列举了,按我们的需要进行分类列举。
a)如果消化TouchDown,按照前面给出的关系,则不可能产生OnLongClick事件。事实是同过我的测试,在这个条件下我对TouchUp是否被消化和操作是长按还是短按4种情况都进行测试,结果都是不产生OnLongClick事件。
b)不消化TouchDown,下面对TouchUp是否被消化又分为两种情况:
bx)不消化TouchDown,不消化TouchUp,对长按和短按分别测试,根据前面给出的关系我们可以推断出长按产生OnLongClick,短按不产生OnLongClick
bx1)程序:不消化TouchDown,不消化TouchUp,----操作:短时间单击按钮----结果:不产生OnLongClick事件
bx2)程序:不消化TouchDown,不消化TouchUp,----操作:长时间单击按钮----结果:产生OnLongClick事件
测试结果满足我们的推断。
by)不消化TouchDown,消化TouchUp,对长按和短按分别测试,根据前面给出的关系我们可以推断出不论长按还是短按,都会产生OnLongClick事件。
by1)程序:不消化TouchDown,消化TouchUp,----操作:短时间单击按钮----结果:产生OnLongClick事件
by2)程序:不消化TouchDown,消化TouchUp,----操作:长时间单击按钮----结果:产生OnLongClick事件
测试结果满足我们的推断。
测试完全符合我们的预期,所以前面给出的关系是对的。
补充:OnClickListener和OnLongClickListener的关系,根据汉语的意思了,可能会感觉到这两个事件会有关系。但是事实是他们之间的关系是没有关系,前面已经给出这两个事件产生的条件了,而且是充分条件,这足已说明这两个事件没关系了。
scrollview嵌套HorizontalScrollView卡顿现象解决
开发中经验会遇到滑动里面嵌入滑动的问题,但是这种情况下触摸事件就会发生冲突。导致滑动非常卡,甚至出现程序停止响应。这种情况下我们一般需要重写view。下面给出重新scrollview的方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class CustomScrollView extends ScrollView { private GestureDetector mGestureDetector; View.OnTouchListener mGestureListener; public CustomScrollView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(new YScrollDetector()); setFadingEdgeLength(0); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev); } // Return false if we're scrolling in the x direction class YScrollDetector extends SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if(Math.abs(distanceY) > Math.abs(distanceX)) { return true; } return false; } } } |
Android 编程下Touch 事件的分发和消费机制和OnTouchListener,OnClickListener和OnLongClickListener的关系的更多相关文章
- Android 编程下 Touch 事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- Android 编程下Touch 事件的分发和消费机制
1.事件分发:public boolean dispatchTouchEvent(MotionEvent ev) Touch 事件发生时 Activity 的 dispatchTouchEvent(M ...
- Android事件分发机制(一) Touch 事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- Touch 事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- 事件之Touch 事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- touch事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- Android中的Touch事件
Android中的Touch事件处理 主要内容 Activity或View类的onTouchEvent()回调函数会接收到touch事件. 一个完整的手势是从ACTION_DOWN开始,到ACTION ...
- 通俗理解Android事件分发与消费机制
深入:Android Touch事件传递机制全面解析(从WMS到View树) 通俗理解Android事件分发与消费机制 说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与Li ...
- View,ViewGroup的Touch事件的分发机制
原帖地址:http://blog.csdn.net/xiaanming/article/details/21696315 ViewGroup的事件分发机制 我们用手指去触摸Android手机屏幕,就会 ...
随机推荐
- Clang编译选项和Pass构建
编译选项相关: 想要添加的选项,以我添加的-fdpu为例子 能通过clang --help得到的选项,整体需要一个解析文件(好像在LLVM项目中都是通过后缀名为xxx.td和xxx.def的文件来进行 ...
- 查询服务商的当月提审限额和加急次数(Quota) 调用遇到问题的来说说是什么情况{"errcode":-1,"errmsg":"system error hint: [_KbPJA05231543]"}
感觉完全是按照微信官方的要求来的,还是提示错误.大家有遇到吗?在微信开发者社区里搜索相关问题,也是有人遇到这样的错误. 还是根据社区里说的,换过用开放平台的component accesstoken ...
- opengl学习-利用模板测试勾画物体轮廓中出现的一个问题
我在学习OpenGL模板测试勾画物体轮廓的时候,出现了这个问题: 这个出现的原因就是,改变摄像机的时候,每次绘制,上次绘制中模板缓冲区的数据没有清除的原因.也就是在while循环开始的时候,glCle ...
- Dell服务器硬件监控,使用omreport出现object not found 错误解决
一.监控告警 登录目标主机,查看dataeng服务 [root@push-- src]# systemctl status dataeng ● dataeng.service - LSB: Syste ...
- 生产者消费者问题--synchronized
# 代码 public class App { public static void main(String[] args) { Depot depot = new Depot(100); Produ ...
- java8学习之比较器详解与类型推断特例
比较器详解: 这次来对比较器进行一个学习,比较器(Comparator)这个是在JDK1.2就提出的概念,只是说JAVA8针对它进行了一定的扩充,更加方便咱们使用,其中唯一的抽象方法如下: 而JAVA ...
- string::find_first_not_of
string (1) size_t find_first_not_of (const string& str, size_t pos = 0) const noexcept; c-string ...
- nginx反向代理原理及配置详解
nginx概述nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外n ...
- 【鸽】poj3311 Hie with the Pie[状压DP+Floyd]
题解网上一搜一大坨的,不用复述了吧. 只是觉得网上dp方程没多大问题,但是状态的表示含义模糊.不同于正常哈密顿路径求解,状态表示应当改一下. 首先定义一次移动为从一个点经过若干个点到达另一个点,则$f ...
- python之路-笔录2[CSS&JS]
*** 目录 *** 1. 块级标签与行内标签 2. css常用清除样式 3. 两种清除浮动的方式 4. CSS学习 5. JS 学习 *** END *** 1. 块级标签与行内标签 常见的块级元素 ...