安卓开发之屏蔽按键抖动,连击,长按事件

博客: 安卓之家
微博: 追风917
CSDN: 蒋朋的家
简书: 追风917

每日一景

缘由


今天来个小知识点,也许遇到的人不多,但还是记录下。现在安卓机很少有实体键,老罗的情怀也只剩下一丝丝。但是除去手机,其他一些设备,比如电视,盒子等很多还有实体键,那么实体键在按下后就有一些问题,“抖动”和“连击”。

在开发中,我这里有一个很重要的操作,是实体键触发的,在实际测试中,会出现按下一次,多次触发的问题,那么就需要解决下,其实,解决方法也不难,我们开始吧。

“抖动”,“连击”


“抖动”和“连击”是类似的错误操作,可以根据时间来判断,和双击退出 app 的操作是一样的,因此可以重写 onKeyDown 方法:

这里以音量-为例

    private static double DOUBLE_CLICK_TIME = 0L;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN ) {
            if ((System.currentTimeMillis() - DOUBLE_CLICK_TIME) > 1500) {//这里测试1500ms比较合适
                DOUBLE_CLICK_TIME = System.currentTimeMillis();

                //这里执行单击后的操作
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

这里很好理解,只有两次点击的时间大于 1500ms 才有效,那么抖动和连击都是无效的。

”长按“


默认情况下,我们不做处理的话,一直按住某个按键,是多次单击操作,大家一直按住音量-就会把声音减小到最小。

如果我不做处理,用户一直按着这个键,或者时间稍长,就相当于按了多次,这会导致误操作,因此需要特殊照顾下咯。

直接重写 onKeyLongPress 方法,测试,不调用,那么,肯定是哪里拦截了,google 了下,在万能的 StackOverflow 找到答案:

链接:onKeyDown and onKeyLongPress

这里添加了一个 标记:shortPress,

private boolean shortPress = false;

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        shortPress = false;
        Toast.makeText(this, "longPress", Toast.LENGTH_LONG).show();
        return true; 
    } 
    //Just return false because the super call does always the same (returning false) 
    return false; 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        if(event.getAction() == KeyEvent.ACTION_DOWN){
            event.startTracking();
            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){
            Toast.makeText(this, "shortPress", Toast.LENGTH_LONG).show();
        } else { 
            //Don't handle longpress here, because the user will have to get his finger back up first 
        } 
        shortPress = false;
        return true; 
    } 
    return super.onKeyUp(keyCode, event);
} 

综合解决


综合上面的分析,把两种情况综合起来,最终解决方案如下:

private static double DOUBLE_CLICK_TIME = 0L;
private boolean shortPress = false;

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        shortPress = false;
        Toast.makeText(this, "longPress", Toast.LENGTH_LONG).show();
        return true; 
    } 
    //Just return false because the super call does always the same (returning false) 
    return false; 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        if(event.getAction() == KeyEvent.ACTION_DOWN){
            event.startTracking();
            if(event.getRepeatCount() == 0){
                shortPress = true;

                if ((System.currentTimeMillis() - DOUBLE_CLICK_TIME) > 1500) {//这里测试1500ms比较合适
                DOUBLE_CLICK_TIME = System.currentTimeMillis();

                //这里执行单击后的操作

                }
                return true; 
            } 

        } 
    } 
    return super.onKeyDown(keyCode, event);
} 

@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        if(shortPress){
            Toast.makeText(this, "shortPress", Toast.LENGTH_LONG).show();
        } else { 
            //Don't handle longpress here, because the user will have to get his finger back up first 
        } 
        shortPress = false;
        return true; 
    } 
    return super.onKeyUp(keyCode, event);
} 

好了,到这里就结束了。

最后,非常感谢您的阅读,有任何疑问,可以后面评论,谢谢!

神奇的安卓开发网站:http://androidcat.com/

安卓开源库收集整理:https://github.com/XXApple/AndroidLibs

分享是一种美德,更是一种生活方式!!

也许你会说我是一个梦想者,但我不是唯一的一个。

悦分享,越快乐^_^

欢迎交流,转载请注明出处,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值