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

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

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

由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在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代码  
1     package com.jerome.util;    2         3     import android.content.Context;    4     import android.os.Handler;    5     import android.util.Log;    6     import android.view.KeyEvent;    7         8     public class KeyUtil {    9         private boolean isVolumeDown = false;   10         private boolean isVolumeUp = false;   11         private boolean isMenu = false;   12         private int currentKeyCode = 0;   13        14         private static Boolean isDoubleClick = false;   15         private static Boolean isLongClick = false;   16        17         CheckForLongPress mPendingCheckForLongPress = null;   18         CheckForDoublePress mPendingCheckForDoublePress = null;   19         Handler mHandler = new Handler();   20        21         Context mContext = null;   22         private String TAG = "";   23        24         public KeyUtil(Context context, String tag) {   25             mContext = context;   26             TAG = tag;   27         }   28        29         public void dispatchKeyEvent(KeyEvent event) {   30             int keycode = event.getKeyCode();   31        32             // 有不同按键按下,取消长按、短按的判断   33             if (currentKeyCode != keycode) {   34                 removeLongPressCallback();   35                 isDoubleClick = false;   36             }   37        38             // 处理长按、单击、双击按键   39             if (event.getAction() == KeyEvent.ACTION_DOWN) {   40                 checkForLongClick(event);   41             } else if (event.getAction() == KeyEvent.ACTION_UP) {   42                 checkForDoubleClick(event);   43             }   44        45             if (keycode == KeyEvent.KEYCODE_VOLUME_DOWN) {   46                 if (event.getAction() == KeyEvent.ACTION_DOWN) {   47                     isVolumeDown = true;   48                 } else if (event.getAction() == KeyEvent.ACTION_UP) {   49                     isVolumeDown = false;   50                 }   51             } else if (keycode == KeyEvent.KEYCODE_VOLUME_UP) {   52                 if (event.getAction() == KeyEvent.ACTION_DOWN) {   53                     isVolumeUp = true;   54                 } else if (event.getAction() == KeyEvent.ACTION_UP) {   55                     isVolumeUp = false;   56                 }   57             } else if (keycode == KeyEvent.KEYCODE_MENU) {   58                 if (event.getAction() == KeyEvent.ACTION_DOWN) {   59                     isMenu = true;   60                 } else if (event.getAction() == KeyEvent.ACTION_UP) {   61                     isMenu = true;   62                 }   63             }   64        65             // 判断组合按键   66             if (isVolumeDown   67                     && isVolumeUp   68                     && isMenu   69                     && (keycode == KeyEvent.KEYCODE_VOLUME_UP   70                             || keycode == KeyEvent.KEYCODE_VOLUME_DOWN || keycode == KeyEvent.KEYCODE_MENU)   71                     && event.getAction() == KeyEvent.ACTION_DOWN) {   72                 //组合按键事件处理;   73                 isVolumeDown = false;   74                 isVolumeUp = false;   75                 isMenu = false;   76             }   77         }   78        79         private void removeLongPressCallback() {   80             if (mPendingCheckForLongPress != null) {   81                 mHandler.removeCallbacks(mPendingCheckForLongPress);   82             }   83         }   84        85         private void checkForLongClick(KeyEvent event) {   86             int count = event.getRepeatCount();   87             int keycode = event.getKeyCode();   88             if (count == 0) {   89                 currentKeyCode = keycode;   90             } else {   91                 return;   92             }   93             if (mPendingCheckForLongPress == null) {   94                 mPendingCheckForLongPress = new CheckForLongPress();   95             }   96             mPendingCheckForLongPress.setKeycode(event.getKeyCode());   97             mHandler.postDelayed(mPendingCheckForLongPress, 1000);   98         }   99       100         class CheckForLongPress implements Runnable {  101       102             int currentKeycode = 0;  103       104             public void run() {  105                 isLongClick = true;  106                 longPress(currentKeycode);  107             }  108       109             public void setKeycode(int keycode) {  110                 currentKeycode = keycode;  111             }  112         }  113       114         private void longPress(int keycode) {  115             Log.i(TAG, "--longPress 长按事件--" + keycode);  116         }  117       118         private void singleClick(int keycode) {  119             Log.i(TAG, "--singleClick 单击事件--" + keycode);  120         }  121       122         private void doublePress(int keycode) {  123             Log.i(TAG, "---doublePress 双击事件--" + keycode);  124         }  125       126         private void checkForDoubleClick(KeyEvent event) {  127             // 有长按时间发生,则不处理单击、双击事件  128             removeLongPressCallback();  129             if (isLongClick) {  130                 isLongClick = false;  131                 return;  132             }  133       134             if (!isDoubleClick) {  135                 isDoubleClick = true;  136                 if (mPendingCheckForDoublePress == null) {  137                     mPendingCheckForDoublePress = new CheckForDoublePress();  138                 }  139                 mPendingCheckForDoublePress.setKeycode(event.getKeyCode());  140                 mHandler.postDelayed(mPendingCheckForDoublePress, 500);  141             } else {  142                 // 500ms内两次单击,触发双击  143                 isDoubleClick = false;  144                 doublePress(event.getKeyCode());  145             }  146         }  147       148         class CheckForDoublePress implements Runnable {  149       150             int currentKeycode = 0;  151       152             public void run() {  153                 if (isDoubleClick) {  154                     singleClick(currentKeycode);  155                 }  156                 isDoubleClick = false;  157             }  158       159             public void setKeycode(int keycode) {  160                 currentKeycode = keycode;  161             }  162         }  163       164         private void removeDoublePressCallback() {  165             if (mPendingCheckForDoublePress != null) {  166                 mHandler.removeCallbacks(mPendingCheckForDoublePress);  167             }  168         }  169     }

注意:

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

 

转自:http://gqdy365.iteye.com/blog/2164237

转载于:https://www.cnblogs.com/zl1991/p/5127464.html

你可能感兴趣的文章
MapReduce
查看>>
找工作——JVM内存管理
查看>>
【Flask】在Flask中使用logger
查看>>
好系统重装助手教你如何让win10系统快速开机
查看>>
linux开机启动
查看>>
BZOJ 1101 [POI2007]Zap 【莫比乌斯反演】
查看>>
SQL Server-The target principal name is incorrect. Cannot generate SSPI context
查看>>
AS3全局与局部坐标转换
查看>>
Java内部类详解
查看>>
初识Twisted(一)
查看>>
linux 软件安装篇
查看>>
Sql server数据库大小写敏感设置
查看>>
JAVA多线程-内存模型、三大特性、线程池
查看>>
RxJS速成 (下)
查看>>
无锁栈与无锁队列
查看>>
微信开发第8章 通过accesstoken将长连接转换为短链接
查看>>
[刷题]Codeforces 785D - Anton and School - 2
查看>>
四川红油的制法
查看>>
Java重写《C经典100题》 --21
查看>>
【Android基础】Fragment 详解之Fragment生命周期
查看>>