卧疾丰暇豫,翰墨时间作。这篇文章主要讲述Android系统中自定义按键的短按双击长按事件相关的知识,希望能为你提供帮助。
在项目中碰到这样的问题:
由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在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); } } }
【Android系统中自定义按键的短按双击长按事件】注意:
只有Action Down状态下RepeatCount才会> 0,避免长按和单击事件混淆;
推荐阅读
- Android体系结构及activity生命周期
- Android基础性能检测与分析
- android 开发Handler源码剖析
- Tesseract OCR集成Android Studio实现OCR识别
- 如何保护你的服务器免受勒索软件的侵害(方法简介)
- 如何在Windows 10上取消模糊图片(10种最佳修复方法)
- 如何永久删除激活Windows 10水印(解决方法指南)
- Android和iPhone的16款最佳陌生人视频聊天应用推荐合集
- Windows 10的16款最佳语音软件推荐合集(哪个最适合你())