大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
触摸事件在Android手机中有多重要不言而喻,用户的每次操作都和它有关。不知道大家有没有见过一些自定义的控件有这样的问题:当单手操作的时候,没有问题,但是当第二根手指头放上去的时候,该View中的内容就会“跳动一下”,如果有这样问题的控件,就是没有处理多点触控。该篇内容主要讲解MotionEvent对象中的多点触控信息,以及RecyclerView对于这种多点触控是如何处理的。MotionEvent又是啥呢?用来记录用户在屏幕中的触摸信息的对象。假如你点了一下屏幕(假如你手没抖,而且速度很快),这个时候就会产生两个MotionEvent对象(UP和DOWM)。
兰考ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!
一次完整的触摸事件流(官方叫gesture)至少包括ACTION_DOWN和ACTION_UP两个Event(手指触摸的情况,不考虑使用鼠标的情况,本文后面所描述的所有情况都是手指触摸的情况)。前面提到了Event的ACTION,我们一般有两个方法可以取到ACTION,一个是 getAction() ,还有一个就是 getActionMasked() 。这两个方法有什么区别呢?action中包含了Pointer的Index,而actionMasked中不包含这个Index。那什么又是Pointer呢?这就涉及到该篇内容要重点讨论的多点触控。可以理解成每一个触控点,通俗点讲就是你放在屏幕上的手指头。我们一般都用ActionMasked这个方法来拿这些Action。下面就简单来说明一下这些常见的Event。
第一根手指头触摸到屏幕(之前屏幕上没有手指头),一次事件触摸流的开始,很简单,但是很重要,这里也要简单的提一下,在ViewGroup中也是根据这次事件的坐标来决定该次事件流交给谁来处理,直到这次事件流完成(ACTION_UP)。
就是你的手指头在屏幕上滑动,就会产生这个事件。
最后一根手指头离开屏幕(屏幕上没有手指头了),标志着该次事件流已经完成。
这次事件流被取消了,虽然还没有完成,一般是ViewGroup经过某种条件判断会设置这样的ACTION。
当屏幕上已经有手指头的时候,再按一个手指头下去就会触发这个事件。
当手指头离开屏幕,同时屏幕上还有手指头的时候就会触发这个事件。
如果你的自定义控件处理好了上面的6种ACTION,那么你的控件对触摸的处理就很好了,因为RecyclerView就只是处理了这6种Event。
在一个MotionEvent对象中,包含了你在屏幕上所有的触摸点信息,他默认会有一个类似于active的触摸点,可以通过方法 getActionIndex() 拿到这个触摸点的Index,然后再通过方法 getPointerId() 能拿到这个触摸点的Id,Id通过 findPointerIndex() ,能再拿到这个Index。这里需要注意的是在一次事件流中,同一个触摸点的Index是可能发生改变的,但是Id是不会改变的。在方法 getX() 和 getY() 中都可以传一个Index来拿你想要的触摸点的坐标,不止这两个方法可以传入index,其他的读者自己去研究了。下面我们来讨论下不同情况下active的默认触摸点都是哪些点呢?
这些ACTIONs默认的active触摸点Index都是0,也就是说这些事件如果你的初次点击屏幕的手指头没有离开屏幕,那就一直是这个点,如果这个手指头已经离开屏幕,那这个点就变成了第二个点击屏幕的点,依次类推。
默认active触摸点是新点击到屏幕上的那个点,但是在后续的move中这个默认index又回变成0。这里也可以简单解释下文章开篇中提到的“跳一下”的Bug:因为在第二个手指头点击屏幕的瞬间,active的触摸点为第二个手指头,这个时候默认的坐标也是第二个指头,后续的move事件中默认的active触摸点又会变成第一个手指头,所以会出现跳一下的Bug。
这个Event和ACTION_POINTER_DOWN类似,只是默认的active的Index变成了离开屏幕的那个触摸点。
下面我们来看看RecyclerView中是如何来处理多点触控的。
这里简单说明下:一个手指到滑动就不说了,当屏幕上有新的手指加入时(之前屏幕上已经有手指头了),这个新加入的手指就会接管RecyclerView的滑动。当有手指头离开屏幕时(屏幕上还有其他的手指头),这个时候如果离开的手指头刚好时接管滑动的那个手指头,这个时候就会找index为0或着1的手指头重新接管滑动;如果离开的不是接管滑动的手指头,就不用管。
到这里多点触控相关的内容就没了,如果有错误的地方,欢迎大家指出来。后面可能还会有触摸事件的发送和滚动相关内容。
你要先描述你要实现什么样的功能,再贴代码,别人看起来更清晰些。
你的主要问题就是两个事件都响应了相同的功能,造成冲突,对吧?那么你可以设置一个成员变量(或者静态变量)比较mHasHandled,先响应的事件把它设置为true,后响应的事件监测到它已经是true了就不再处理了。
不是屏蔽了,是button、textView 这些组件把触摸事件截获了,你可能需要在acticity中调用interrupetOntouchEnent() 直接阻断触摸事件,然后在ontouchEvent()中处理
一、触摸事件
ontouchstart、ontouchmove、ontouchend、ontouchcancel
目前移动端浏览器均支持这4个触摸事件,包括IE。由于触屏也支持MouseEvent,因此他们的顺序是需要注意的:touchstart → mouseover → mousemove → mousedown → mouseup → click1
Apple在iOS 2.0中引入了 触摸事件API ,Android正迎头赶上这一事实标准,缩小差距。最近一个W3C工作组正合力制定这一 触摸事件规范 。
二、规范
这里我们介绍几种普及得比较好的触摸事件,你可以在绝大多数现代浏览器中来测试这一事件(必须是触屏设备哦):
touchstart: 触摸开始的时候触发
touchmove: 手指在屏幕上滑动的时候触发
touchend: 触摸结束的时候触发
而每个触摸事件都包括了三个触摸列表,每个列表里包含了对应的一系列触摸点(用来实现多点触控):
touches: 当前位于屏幕上的所有手指的列表。
targetTouches: 位于当前DOM元素上手指的列表。
changedTouches: 涉及当前事件手指的列表。
每个触摸点由包含了如下触摸信息(常用):
identifier: 一个数值,唯一标识触摸会话(touch session)中的当前手指。一般为从0开始的流水号(android4.1,uc)
target: DOM元素,是动作所针对的目标。
pageX / pageX / clientX / clientY/screenX/screenY : 一个数值,动作在屏幕上发生的位置(page包含滚动距离,client不包含滚动距离,screen则以屏幕为基准)。
radiusX / radiusY/ rotationAngle: 画出大约相当于手指形状的椭圆形,分别为椭圆形的两个半径和旋转角度。初步测试浏览器不支持,好在功能不常用,欢迎大家反馈。
有了这些信息,我们就可以依据这些事件信息为用户提供不同的反馈了。
下面,我将为大家展示一个小demo,用touchmove实现的单指拖动:
三、手势事件
手势是指利用多点触控进行旋转、拉伸等操作,例如图片、网页的放大、旋转。需要两个或以上的手指同时触摸时才会触发手势事件。关于缩放我们需要注意的一点 是元素的位置坐标:我们通常使用offsetX、getBoundingClientRect等方法获取元素的位置坐标,但在手机浏览器中页面经常会在使 用中被缩放,那缩放后的元素坐标会改变吗?答案是有所差异。用一个情景来说明这个问题:页面A加载完成后, JavaScript 获 取到该元素在document中的坐标为(100,100),接着用户放大了页面,此时用JavaScript再次输出元素坐标,依然还是 (100,100),但该元素在屏幕上的响应区域会根据缩放比例产生偏移。你可以打开那个打砖块游戏demo,等页面完全加载完成后,再放大,此时你会发 现即使手指触摸在“touch here”区域外部,也可以控制到球板,因为区域发生了偏移。除非页面刷新或者恢复缩放,否则偏移量将一直存在。
四、重力感应
重力感应较简单,只需要为body节点添加onorientationchange事件即可。在此事件中由window.orientation属性得到代表当前手机方向的数值。window.orientation的值列表如下:
0:与页面首次加载时的方向一致
-90:相对原始方向顺时针转了90°
180:转了180°
90:逆时针转了90°据我测试,Android2.1尚未支持重力感应。以上即目前的触屏事件,这些事件尚未并入标准,但已被广泛使用。本人Android2.1,未在其他环境下测试。
onTouchEvent触屏事件 和 onKeyUp键盘事件分别实现不同的功能:
onTouchEvent可以得到触屏的起始点(手刚接触屏幕)和结束点(手离开屏幕)的 坐标(x,y),这样可以根据坐标来判断手势的走向,进而做出事件响应。
onKeyUp是消息驱动事件,可以直接做出响应。