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);
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 13,085评论 2 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,109评论 25 709
  • 面试必背 会舍弃、总结概括——根据我这些年面试和看面试题搜集过来的知识点汇总而来 建议根据我的写的面试应对思路中的...
    luoyangzk阅读 6,838评论 6 173
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,688评论 0 17
  • 快上课了,我提前进入教室,只见小冯同学站在讲台前,手在拨弄粉笔盒。 我:小冯同学,怎么啦? 冯:粉笔盒坏了,我只是...
    飞飞老师Fy阅读 550评论 0 0