标签:
在项目中碰到这样的问题:
由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在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、组合按键:用变量记录每个按键的状态,再进行判断;
具体代码如下:
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
标签:
原文地址:http://www.cnblogs.com/zl1991/p/5127464.html