为自定义的View添加长按事件
以前开发画板组件时,要添加一个长按监听事件,这个画板实际上就是继承自View的一个自定义组件。
首先,设置好长按事件发生时要触发的操作:
private class LongPressRunnable implements Runnable {
private int x, y;
public void setPressLocation(float x, float y) {
this.x = (int) x;
this.y = (int) y;
}
@Override
public void run() {
Log.i("发生长按事件,位置在:" + x + "、" + y);
}
}
接下来,编写自定义的View,重点在覆写dispatchTouchEvent(MotionEvent)方法:
public class MyView extends View {
...
/**
* 当长按事件发生时,要触发的任务
*/
private LongPressRunnable longPressRunnable = new LongPressRunnable();
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (longPressRunnable != null) {
//TODO 这里可以增加一些规则,比如:模糊XY的判定,使长按更容易触发
removeCallbacks(longPressRunnable);
if (event.getAction() == MotionEvent.ACTION_DOWN
&& event.getPointerCount() == 1) {
postCheckForLongTouch(event.getX(), event.getY());
}
}
return true;
}
private void postCheckForLongTouch(float x, float y) {
longPressRunnable.setPressLocation(x, y);
postDelayed(longPressRunnable, 500);
}
}
原理很简单,长按事件的本质是:手指触摸某个点保持不移动,也就是touch的时候仅仅发生ACTION_DOWN事件,不发生ACTION_MOVE和ACTION_UP事件,这样经过一定时间(这里是500毫秒)则成功触发长按事件。
所以一个长按事件的周期是On Touch Down ---> 500ms ---> On Long Press。
接下来分析上面的实现:当我们收到Touch事件时,不管是什么事件,先删除上一次设置好的longPressRunnable,
removeCallbacks(longPressRunnable);
这意味着上一次触摸周期没有触发长按操作。
然后判断事件类型,如果是“单指ACTION_DOWN”事件则表明有可能会触发长按操作,那么我们通过View.postDelayed()方法将longPressRunnable放进这个View所在线程的任务队列中,并延迟500毫秒执行,
if (event.getAction() == MotionEvent.ACTION_DOWN && event.getPointerCount() == 1) {
postCheckForLongTouch(event.getX(), event.getY());
}
private void postCheckForLongTouch(float x, float y) {
longPressRunnable.setPressLocation(x, y);
postDelayed(longPressRunnable, 500);
}
如果在这500毫秒内,用户的手指没有移动或抬起,也就是不会有任何touch事件到来,则该longPressRunnable会在500毫秒后运行,一个长按操作就完成了。
如果在这500毫秒内用户的手指移动或抬起了,那么新的touch事件到来,longPressRunnable也会被移除。
以上就是整个实现,这个实现有个需要优化的地方,就是//TODO那里,由于人的手指并没有那么精细,在长按过程中可能会有一点移动,这往往会导致长按失败,所以我们可以在//TODO那里添加对ACTION_MOVE事件的处理,忽略一些细微的移动事件,留给读者自行实现吧:D
为自定义的View添加长按事件的更多相关文章
- 给View 添加手势,点击无反应 如何给View添加点击事件,手势方法
项目中有很多地方需要添加点击事件,重复代码很多,所以做了一个UIView的分类,专门做点击事件使用.项目地址:UIView-Tap 代码很简单,主要有一点就是注意分类不能直接添加属性,需要用到运行时相 ...
- 为 UIButton 添加长按事件
UIButton *aBtn=[UIButtonbuttonWithType:UIButtonTypeCustom]; [aBtn setFrame:CGRectMake(40, 100, 60, 6 ...
- datatables添加长按事件
长按事件 $.fn.longPress = function (fn) { var timeout = undefined; var $this = this; for (var i = 0; i & ...
- View,ViewGroup的Touch事件的分发机制
原帖地址:http://blog.csdn.net/xiaanming/article/details/21696315 ViewGroup的事件分发机制 我们用手指去触摸Android手机屏幕,就会 ...
- TextView AutoLink, ClikSpan 与长按事件冲突的解决
前言 首先,我们先来复习一下 autoLink 和 ClickableSpan 是干什么用的. autoLink 当中有五个属性值:分别是 phone.email.map.web.all 和 none ...
- Andriod 从源码的角度详解View,ViewGroup的Touch事件的分发机制
转自:xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/21696315) 今天这篇文章主要分析的是Android的事件分发机制, ...
- 【Android - 自定义View】之不同事件的处理
在Android的自定义View中,往往需要处理一系列的事件,如触摸事件.双击事件.缩放事件等.本文将这些事件及其处理进行总结.本文将持续更新,将我在自定义View的实践中用到的事件及其处理进行总结. ...
- Android系统中自定义按键的短按、双击、长按事件
在项目中碰到这样的问题: 由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在APP层对按键事件(keyevent)做分解处理,模拟Android系统做法,把keyevent分解成: 1.单击 ...
- Android自定义长按事件
Android系统自带了长按事件,setOnLongClickListener即可监听.但是有时候,你不希望用系统的长按事件,比如当希望长按的时间更长一点的时候.这时候就需要自己来定义这个长按事件了. ...
随机推荐
- MVC學習網站
http://www.cnblogs.com/haogj/archive/2011/11/23/2246032.html
- Qt Creater中的.pro文件和.pri文件
初学Qt,使用Qt Creater打开Demo "QT 3D Basic Shapes C++ Example",发现除了pro文件外,还有一个pri文件,在此小白一下! *.pr ...
- 阿里云提出的漏洞(Phpcms V9某处逻辑问题导致getshell漏洞解决方法)的问题
最近从阿里云云盾检测流出来的,相比使用阿里云服务器的朋友已经收到漏洞提醒:Phpcms V9某处逻辑问题导致getshell漏洞解决方法,这个漏洞怎么办呢?CMSYOU在这里找到针对性解决办法分享给大 ...
- SQL 语句判断记录是否存在(最简洁简单性能最优)
今天查了下,发现网上的没有一个sql语句写的好的. 判断记录是否存在,要不是语句不够简洁,要不就是性能有很大问题. 我进行了优化后,最简洁简单性能最优的的sql语句,用来判断表中的记录是否存在: se ...
- js合并.css合并工具
http://www.neoease.com/css-javascript-combo-tool/ http://www.neoease.com/minimize-javascript-files-u ...
- Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
https://www.cnblogs.com/alexyuyu/articles/3454907.html
- rpc框架 SimpleXMLRP
一台电脑去控制另一台电脑干事情,最常见的就是web. 用户get/post一个url,服务端根据url地址和参数去做相应的事情把结果返回给客户端. server.py #coding=utf8 fro ...
- python连接mysql数据库封装
源码: import pymysql class MysqlConnect(object): # 魔术方法, 初始化, 构造函数 def __init__(self, host, user, pass ...
- vue中使用动态echart图表
<template> <div class="block"> <div class="title">展会实时人流里统计< ...
- c 各种编译器(gcc clang)
很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后, 对于xcode中很多配置型的需求修改起来都会得心应手,因此有必要了解透 ...