• 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代码  收藏代码
      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

  • 相关阅读:
    [刘阳Java]_eayui-pagination分页组件_第5讲
    [刘阳Java]_easyui-draggable拖动组件_第4讲
    [刘阳Java]_easyui-panel组件入门级_第3讲
    [刘阳Java]_TortoiseSVN基础应用_第1讲
    [刘阳Java]_SpringMVC文件上传第2季_第11讲
    [刘阳Java]_Spring中IntrospectorCleanupListener的用途【补充】_第16讲
    使用fetch代替ajax请求 post传递方式
    react购物车demo
    react-redux异步数据操作
    redux模块化demo
  • 原文地址:https://www.cnblogs.com/zl1991/p/5127464.html
Copyright © 2020-2023  润新知