2018-10-19 Android长按键、短按键识别及处理

在做Android TV项目的过程中,需要识别遥控器长按、短按来做不同的操作。
在网上查找,一般如下(传送门):

在Android中已经有了长按与短按的识别,只是长按识别的时间比较短 ,大概在1s以上就认为是长按了。主要的思路是设置一个标志位,利用事件相应次数函数event.getRepeatCount()来设置标志位。主要用的函数是按键响应的三个函数 onKeyLongPress,onKeyDown和onKeyUp,具体代码如下:

private boolean shortPress = false;
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        shortPress = false;
      //长按要执行的代码
        return true;
    }

    return false;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        if(event.getAction() == KeyEvent.ACTION_DOWN){
            event.startTracking(); //只有执行了这行代码才会调用onKeyLongPress
            if(event.getRepeatCount() == 0){
                shortPress = true;
            }
            return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        if(shortPress){
            //短按要执行的代码
        } 
        shortPress = false;
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

按照上述方法,需要在onKeyUp中处理短按键(一般onKeyDown时就处理了),但是由于我在包含Fragment的activity中,处理逻辑不在activity内,且Fragment没有 onKeyLongPress,onKeyDown和onKeyUp等函数,很难实现对Fragment中具体焦点的处理,所以此方法暂时行不通。


经过摸索,发现不需要使用onKeyLongPress,直接在onKeyDown中调用event.getRepeatCount()判断是否大于0,如果大于0,则认为是长按键,记录标志,然后再onKeyUp中处理长按键即可,(长按按键键时第1次onKeydown 500ms,第2次500ms,第3次及之后没50ms发送一次onKeydown):
代码如下:
···
private boolean isLongPressKey;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_UP:
            if (event.getRepeatCount() != 0) {
                Log.i(TAG, "onKeyDown: long press key");
                isLongPressKey = true;
                return true;
            }
            break;
        default:
            break;
    }

    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_UP:
            if (isLongPressKey) {
                Log.i(TAG, "onKeyUp: long");
                // 长按键的处理逻辑
                isLongPressKey = false;
                return true;
            }
            break;
        default:
            break;
    }

    return super.onKeyUp(keyCode, event);
}

···
这样做了之后,有一个问题,长按必须放开后,才响应动作,这样在体验上不是很好,但目前未想到解决办法,待后续研究。

你可能感兴趣的:(2018-10-19 Android长按键、短按键识别及处理)