博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android系统中自定义按键的短按、双击、长按事件
阅读量:5122 次
发布时间:2019-06-13

本文共 4523 字,大约阅读时间需要 15 分钟。

在项目中碰到这样的问题: 

由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在APP层对按键事件(keyevent)做分解处理,模拟Android系统做法,把keyevent分解成: 
1、单击事件:就是普通key的单击; 
2、双击事件:500ms内同一按键单击两次; 
3、长按事件:同一按键长按超过1000ms(系统中长按事件为500ms); 
4、组合按键:两个以上按键同时按住; 
其中的keyevent可以来自Activity、View子类的dispatchKeyEvent方法,也可以是我们自定义的接口,也可以是我们发广播送上来的,根据项目需求; 
关于各事件的原理: 
1、双击事件:每次点击的up事件中启动一个定时(500ms)线程消息,用Handler.postDelayed()方法。 
2、长按事件:每次点击的down事件中启动一个定时(1000ms)线程消息,用Handler.postDelayed()方法,注意:在RepeatCount==0时启动; 
3、组合按键:用变量记录每个按键的状态,再进行判断; 
具体代码如下: Java代码

package com.jerome.util;import android.content.Context;import android.os.Handler;import android.util.Log;import android.view.KeyEvent;public class KeyUtil {	private boolean isVolumeDown = false;	private boolean isVolumeUp = false;	private boolean isMenu = false;	private int currentKeyCode = 0;	private static Boolean isDoubleClick = false;	private static Boolean isLongClick = false;	CheckForLongPress mPendingCheckForLongPress = null;	CheckForDoublePress mPendingCheckForDoublePress = null;	Handler mHandler = new Handler();	Context mContext = null;	private String TAG = "";	public KeyUtil(Context context, String tag) {		mContext = context;		TAG = tag;	}	public void dispatchKeyEvent(KeyEvent event) {		int keycode = event.getKeyCode();		// 有不同按键按下,取消长按、短按的判断		if (currentKeyCode != keycode) {			removeLongPressCallback();			isDoubleClick = false;		}		// 处理长按、单击、双击按键		if (event.getAction() == KeyEvent.ACTION_DOWN) {			checkForLongClick(event);		} else if (event.getAction() == KeyEvent.ACTION_UP) {			checkForDoubleClick(event);		}		if (keycode == KeyEvent.KEYCODE_VOLUME_DOWN) {			if (event.getAction() == KeyEvent.ACTION_DOWN) {				isVolumeDown = true;			} else if (event.getAction() == KeyEvent.ACTION_UP) {				isVolumeDown = false;			}		} else if (keycode == KeyEvent.KEYCODE_VOLUME_UP) {			if (event.getAction() == KeyEvent.ACTION_DOWN) {				isVolumeUp = true;			} else if (event.getAction() == KeyEvent.ACTION_UP) {				isVolumeUp = false;			}		} else if (keycode == KeyEvent.KEYCODE_MENU) {			if (event.getAction() == KeyEvent.ACTION_DOWN) {				isMenu = true;			} else if (event.getAction() == KeyEvent.ACTION_UP) {				isMenu = true;			}		}		// 判断组合按键		if (isVolumeDown				&& isVolumeUp				&& isMenu				&& (keycode == KeyEvent.KEYCODE_VOLUME_UP						|| keycode == KeyEvent.KEYCODE_VOLUME_DOWN || keycode == KeyEvent.KEYCODE_MENU)				&& event.getAction() == KeyEvent.ACTION_DOWN) {			//组合按键事件处理;			isVolumeDown = false;			isVolumeUp = false;			isMenu = false;		}	}	private void removeLongPressCallback() {		if (mPendingCheckForLongPress != null) {			mHandler.removeCallbacks(mPendingCheckForLongPress);		}	}	private void checkForLongClick(KeyEvent event) {		int count = event.getRepeatCount();		int keycode = event.getKeyCode();		if (count == 0) {			currentKeyCode = keycode;		} else {			return;		}		if (mPendingCheckForLongPress == null) {			mPendingCheckForLongPress = new CheckForLongPress();		}		mPendingCheckForLongPress.setKeycode(event.getKeyCode());		mHandler.postDelayed(mPendingCheckForLongPress, 1000);	}	class CheckForLongPress implements Runnable {		int currentKeycode = 0;		public void run() {			isLongClick = true;			longPress(currentKeycode);		}		public void setKeycode(int keycode) {			currentKeycode = keycode;		}	}	private void longPress(int keycode) {		Log.i(TAG, "--longPress 长按事件--" + keycode);	}	private void singleClick(int keycode) {		Log.i(TAG, "--singleClick 单击事件--" + keycode);	}	private void doublePress(int keycode) {		Log.i(TAG, "---doublePress 双击事件--" + keycode);	}	private void checkForDoubleClick(KeyEvent event) {		// 有长按时间发生,则不处理单击、双击事件		removeLongPressCallback();		if (isLongClick) {			isLongClick = false;			return;		}		if (!isDoubleClick) {			isDoubleClick = true;			if (mPendingCheckForDoublePress == null) {				mPendingCheckForDoublePress = new CheckForDoublePress();			}			mPendingCheckForDoublePress.setKeycode(event.getKeyCode());			mHandler.postDelayed(mPendingCheckForDoublePress, 500);		} else {			// 500ms内两次单击,触发双击			isDoubleClick = false;			doublePress(event.getKeyCode());		}	}	class CheckForDoublePress implements Runnable {		int currentKeycode = 0;		public void run() {			if (isDoubleClick) {				singleClick(currentKeycode);			}			isDoubleClick = false;		}		public void setKeycode(int keycode) {			currentKeycode = keycode;		}	}	private void removeDoublePressCallback() {		if (mPendingCheckForDoublePress != null) {			mHandler.removeCallbacks(mPendingCheckForDoublePress);		}	}}

  注意: 

只有Action Down状态下RepeatCount才会>0,避免长按和单击事件混淆;

转载于:https://www.cnblogs.com/muhuacat/p/6086308.html

你可能感兴趣的文章
行测(爆发篇)之数学运算怎能轻言放弃?!
查看>>
socket 编程入门教程(三)TCP原理:4、设计TCP socket的类(下)
查看>>
最简洁的IP判断正则表达式
查看>>
第2次作业:微博软件分析
查看>>
Python__slots__详解
查看>>
在 win 10 中使用sql 2012 附加低版本数据失败的解决办法。
查看>>
Algorithmic Graph Drawing in TikZ
查看>>
SQL2000数据库密码被替换,重置密码提示未能找到存储过程sp_password解决方案
查看>>
王之泰201771010131《面向对象程序设计(java)》第二周学习总结
查看>>
C++入门经典-例6.2-将二维数组进行行列对换
查看>>
video相关参数、操作和事件
查看>>
SharePoint 2010 PowerShell 系列 之 应用总结
查看>>
zepto的scrollTo,实现锚点跳转
查看>>
深入浅出的webpack构建工具--webpack4+vue+router项目架构(十四)
查看>>
git指令大全
查看>>
无服务器端的UDP群聊功能剖析(新增QQ表情功能)
查看>>
nginx配置location总结及rewrite规则写法
查看>>
弹框和遮罩层组件
查看>>
linux 下安装mysql相关笔记
查看>>
C# 二维码/条形码入门操作
查看>>