android 按键双击,实现Android监控任意控件或按键双击事件方法
为了实现对Android任意控件和按键进行双击事件的监听,所以写了一个可以在代码中任意移植的解决方法。
一、解决思路
为了实现双击事件的监听,首先需要一个线程来执行两次点击事件的判断,决定是否属于一次双击事件,为了可以实现多次监听,所以在线程中是一个死循环,避免开无数个线程;然后将判断结果通过handler传递出去,由handler对message中携带的boolean数据进行判断,决定回调双击事件监听器中的双击或单击方法,监听器中的事件由用户覆写;最后在自己想要添加双击事件监听的控件或按键的点击事件监听器中创建一个双加事件管理器并启动就可以了。
二、准备工作
1.创建双击事件监听器接口
/**
* Created by 明月春秋 on 2017/11/18.
* 负责对是否双击事件结果的回调监听器
* 方法:
* 1.onSinglePress:用于处理单击事件
* 2.onDoublePress:用于处理双击事件
*/
public interface OnDoubleClickListener {
/**
* 用于处理单击事件
*/
public void onSinglePress();
/**
* 用于处理双击事件
*/
public void onDoublePress();
}
2.创建双击事件处理handler,用来决定是执行监听器中的双击事件还是单击事件
/**
* Created by 明月春秋 on 2017/11/18.
* 负责处理双击事件的handler
* 方法:
* 1.setDoubleRunnable:设置handler处理所在的线程执行体
*/
public class DoubleHandler extends Handler {
private OnDoubleClickListener mListener;//对是否双击结果的回调监听器
private DoubleRunnable mDoubleRunnable;//负责双击事件的线程执行体
/**
* 双击事件处理器的构造函数
* @param listener
* 对是否双击结果的回调监听器
*/
public DoubleHandler(OnDoubleClickListener listener){
super(Looper.getMainLooper());
this.mListener = listener;
}
@Override
public void handleMessage(Message msg) {
if ((boolean)msg.obj){
mListener.onDoublePress();
}
else {
mListener.onSinglePress();
}
//通知双击事件线程执行体,事件已处理完
mDoubleRunnable.setIsStarted(false);
}
/**
* 设置handler处理所在的线程执行体
* @param doubleRunnable
* 传入的当前线程执行体
*/
public void setDoubleRunnable(DoubleRunnable doubleRunnable){
this.mDoubleRunnable = doubleRunnable;
}
}
3.创建执行双击事件判断的线程执行体,在其中进行死循环,一直等待用户的点击,并对相关运行状态进行判断,将双击事件的判断结果发送给前面的DoubleHandler 进行处理
/**
* Created by 明月春秋 on 2017/11/18.
* 负责双击事件的线程执行体
* 方法:
* 1.setPreparedState:设置当前双击事件的执行状态
* 2.setIsStarted:设置线程是否处于一次双击事件判断的阻塞之中
* 3.setDoubleSpan:设置用于判断双击的间隔时间
*/
public class DoubleRunnable implements Runnable {
private DoubleHandler mHandler;//处理点击事件的handler
private boolean isStarted = false;//表示线程是否正处于阻塞中
private boolean isPrepared = false;//表示是否已准备好启动线程
private boolean isDoubleClicked = false;//表示是否被双击
private int doubleSpan;//用于判断双击的间隔时间
/**
* 双击事件线程执行体的构造函数
* @param handler
* 用于处理是否双击事件的handler
*/
public DoubleRunnable(DoubleHandler handler) {
handler.setDoubleRunnable(this);
this.mHandler = handler;
}
@Override
public void run() {
while (true){
//如果没有被点击,则继续下次循环
if (!isPrepared) {
continue;
}
isPrepared = false;
//如果线程处于一次双击事件的阻塞中,则继续下次循环,直至事件结束
if (isStarted){
continue;
}
isStarted = true;
try {
Thread.sleep(doubleSpan);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = mHandler.obtainMessage();
msg.obj = isDoubleClicked;
mHandler.sendMessage(msg);
}
}
/**
* 设置当前双击事件的执行状态
* @param isPrepared
* 是否已被点击(可以执行线程中代码)
* @param isDoubleClicked
* 是否已被双击
*/
public void setPreparedState(boolean isPrepared, boolean isDoubleClicked) {
this.isPrepared = isPrepared;
this.isDoubleClicked = isDoubleClicked;
}
/**
* 设置线程是否处于一次双击事件判断的阻塞之中
* @param isStarted
* 传入是否阻塞开启
*/
public void setIsStarted(boolean isStarted){
this.isStarted = isStarted;
}
/**
* 设置用于判断双击的间隔时间
* @param doubleSpan
* 传入的时间间隔
*/
public void setDoubleSpan(int doubleSpan){
this.doubleSpan = doubleSpan;
}
}
4.最后创建一个双击事件管理器,进行线程的创建管理,并用于启动线程和更新用户的点击时间,之所以在管理器中更新时间并进行判断,是因为可以随时根据用户的点击去更新DoubleRunnable中的双击判断结果,如果在DoubleRunnable中进行时间判断,则会因为判断只会在下一次阻塞循环结束之后才能进行,导致一直是单击事件执行。
/**
* Created by 明月春秋 on 2017/11/18.
* 双击事件的管理器
* 方法:
* 1.start:开启双击事件的线程执行
*/
public class DoubleManager {
private DoubleRunnable mDoubleRunnable = null;//负责双击事件的线程执行体
private Thread mThread = null;//负责双击事件的线程
private long mClickTime = 0;//记录点击时间
private static final int DOUBLE_SPAN = 300;//用于判断双击的间隔时间
/**
* 双击事件管理器的构造函数
* @param doubleRunnable
* 传入负责双击事件的线程执行体
*/
public DoubleManager(DoubleRunnable doubleRunnable){
if (doubleRunnable == null){
return;
}
if (mDoubleRunnable == null){
doubleRunnable.setDoubleSpan(DOUBLE_SPAN);
this.mDoubleRunnable = doubleRunnable;
}
}
/**
* 开启双击事件的线程执行
*/
public void start(){
if (mDoubleRunnable == null){
return;
}
boolean isDoubleClicked = false;
if ((System.currentTimeMillis() - mClickTime) < DOUBLE_SPAN) {
isDoubleClicked = true;
}
else {
isDoubleClicked = false;
mClickTime = System.currentTimeMillis();
}
mDoubleRunnable.setPreparedState(true, isDoubleClicked);
if (mThread == null){
mThread = new Thread(mDoubleRunnable);
mThread.start();
}
}
}
5.接下来就可以在任意控件的单击事件监听器中或按键事件中,进行双击事件的判断了。
public class DoubleClick extends AppCompatActivity {
private DoubleManager doubleManager = null;
private DoubleManager keyDoubleManager = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.button_double_click);
}
public void doubleClick(View view){
if (doubleManager == null){
doubleManager = new DoubleManager(new DoubleRunnable(new DoubleHandler(new OnDoubleClickListener() {
@Override
public void onSinglePress() {
Toast.makeText(DoubleClick.this, "单击", Toast.LENGTH_SHORT).show();
}
@Override
public void onDoublePress() {
Toast.makeText(DoubleClick.this, "双击", Toast.LENGTH_SHORT).show();
}
})));
}
doubleManager.start();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER){
if (keyDoubleManager == null){
keyDoubleManager = new DoubleManager(new DoubleRunnable(new DoubleHandler(new OnDoubleClickListener() {
@Override
public void onSinglePress() {
Toast.makeText(DoubleClick.this, "按键单击", Toast.LENGTH_SHORT).show();
}
@Override
public void onDoublePress() {
Toast.makeText(DoubleClick.this, "按键双击", Toast.LENGTH_SHORT).show();
}
})));
}
keyDoubleManager.start();
}
return super.onKeyDown(keyCode, event);
}
}
运行例子中按键事件时,记得将Button在布局中设为android:visibility="gone",防止按键事件直接点击到按钮上,执行按钮的双击事件监听了。
三、运行效果图
1.执行按钮单击
2.执行按钮双击
3.执行按键单击
4.执行按键双击
四、总结 到此,Android任意控件或按键的双击事件监听就已经全部实现了。只要前面将准备工作做好,就可以随意在任何代码处添加双击事件管理器并执行了,不会对原有代码产生任何影响,如果对本文有什么意见和问题欢迎指正,如果觉得本文可以,请帮忙点个赞,谢谢观看。
android 按键双击,实现Android监控任意控件或按键双击事件方法相关推荐
- Android粒子爆炸特效[可用于任意控件]
小米手机用户可以看到,小米手机在应用卸载时会有一个粒子爆炸的特效效果,对此类动画效果垂涎已久,奈何一直没有机会用.正好最近项目里需要用到粒子爆炸的特效,于是便抽时间自己也试着仿写了一个效果出来. 先看 ...
- android获取该控件在屏幕,android获取屏幕宽高与获取控件宽高(三种方法)
1.获取屏幕宽高 方法1: int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px ...
- Qt 给控件QLineEdit添加clicked事件方法
做Qt开发的会知道QLineEdit是默认没有clicked事件的,但是Qt有很好的一套信号/槽机制,而且Qt是基于C++面向对象的思想来设计的,那么我们就很容易通过自己定义一些类,重写QLineEd ...
- App控件定位:Android 控件介绍及元素定位方法
本文将分享Android相关基础知识和Android APP控件定位工具的使用方法. 目录 Android基础知识 Android布局 Android四大组件 1.activity 2.Service ...
- android 固定底部 布局_Android系统列表控件
在android系统控件中,有多个控件可以展示列表数据. 一.ListView 该组件是android中最常用的一个UI组件,用于实现在屏幕上显示多个内容,以便于我们用手指进行滑动. ListView ...
- android listview添加数据_Android系统列表控件
在android系统控件中,有多个控件可以展示列表数据. 一.ListView 该组件是android中最常用的一个UI组件,用于实现在屏幕上显示多个内容,以便于我们用手指进行滑动. ListView ...
- android自定义控件不显示,解决Android Studio Design界面不显示layout控件的问题
Android Studio更新到3.1.3后,发现拖到Design中的控件在预览界面中不显示: 解决办法: 在Styles.xml中的parent="..."中的Theme前添加 ...
- 【android免root脚本制作】基于控件的操作——auto.js进阶
在[android免root脚本制作]自动坐标操作手机--京东金融程序金果摇钱树自动收金果 之后,想要做进一步优化,因为基于坐标点击如何屏幕被移动之类就会点击错位,不同手机还需去适配坐标,甚是麻烦,所 ...
- 记录学习Android基础的心得05:常用控件(基础篇)
文章目录 前言 一.复合按钮CompoundButton的常见子类 1.单选按钮RadioButton 2.复选框CheckBox 3.开关Switch 二.进度展示控件 1.进度条ProgressB ...
最新文章
- RecyclerView 删除Item 以及删除整个RecyclerView
- android studio x86虚拟机,Android studio在运行虚拟机的时候出现这种情况怎么办?
- js的BOM对象完全解析
- 2020计算机考研初试考试先后顺序,【图片】2020考研,老学长教你如何规划!【计算机考研吧】_百度贴吧...
- rbf神经网络_基于RBF神经网络的监督控制(09)
- Mysql是否开启binlog日志开启方法
- VTK:相互作用之CallData
- Swift之深入解析内存管理的底层原理
- 移动开发框架,第【一】弹:QuoJs 官方文档(汉化版)
- python中的Xpath方法总结
- Python自建collections模块
- 量子传输技术转移一个人需要4500万亿年
- liunx 常用操作
- CCF201712-1 最小差值(100分)
- Python--网络编程-----通过socket收发文件软件开发--面向对象开发
- Laravel 2017 年度调查报告
- 蛋花花分享人工智能概念的诞生与发展
- SpringBoot 接口数据加解密
- soul 总是显示登录聊天服务器,用soul聊天莫名其妙被封了号,并没有发广告就被封...
- chrome pdf android,Android PDF阅读器 (基于谷歌平台的Adobe Reader)
热门文章
- 新安装的微信PC版,退出后聊天记录没了,文件接收失败、错误、打不开,怎么办?
- 连接网络怎么连接无线网络连接服务器,如何解决连接无线网络却不能上网的问题?...
- linux 进入其他磁盘分区,Linux磁盘分区,及磁盘的其他操作
- XMLHttpRequest介绍
- Docker 安装 Mysql , Redis,ElasticSearch,Kibana,RabbitMQ,Zipkin,Nacos,Minio Docker服务器环境搭建
- redis分布式锁实现秒杀活动
- Android扫描枪(PDA)开发
- 澳政府报销房租鼓励青年再就业
- [What is the PBR?] - 对Reflection的误解(漫反射镜面反射)
- 改变工作目录和根目录