按键事件处理

当按键来临时可能会有三种动作

  • ACTION_DOWN:按键被按下
  • ACTION_UP : 按键被释放
  • ACTION_MULTIPLE : 多次重复的按键事件,可通过getRepeatCount获取次数

按键的动作状态可以通过event.getAction()方法来获取。一般只要down和up两种行为。

转载请注明出处

from

海天之蓝

按键事件处理


当然按键也有很多标志位,可以通过event.getFlags()方法来获取按键的标志位。

  • FLAG_SOFT_KEYBOARD:软键盘的按键事件
  • FLAG_KEEP_TOUCH_MODE:在按键状态下就会触摸触摸模式,设置了该标志位可以在按键按下时保持触摸模式
  • FLAG_FROM_SYSTEM:按键事件来自系统,由用户处理,不能被别的三方组件或者应用使用
  • FLAG_EDITOR_ACTION:编辑键
  • FLAG_CANCELED:与事件的up有关,表示按键事件已经被取消了。尤其被用在虚拟触屏按键
  • FLAG_LONG_PRESS:长按事件
  • ...............................


在明白了这些之后,在分析按键之前首先要是弄清楚按键按下时的action,标志等等

来段程序测试下

  @Override
    public boolean dispatchKeyEvent(KeyEvent event) {

        Log.i("fang", "---event--getAction = " + event.getAction());
        Log.i("fang", "---event--getRepeat = " + event.getRepeatCount());
        Log.i("fang", "----event---isLongPress= " + event.isLongPress());
        return true;
    }


比如,短按事件很好说

按键事件处理_第1张图片


短按时先是接收到action_down,然后是action_up


那如果是长按的话,log如下

按键事件处理_第2张图片

长按是down--down--up然后释放时会有个up。

所以有了按键的action的log之后,就可以自己设计在什么情况下去做一些按键的处理,比如我如果想要在长按按键时做一个操作

那么可以有三次查询到该按键的机会

第一次,down,重复次数0 ,非长按

第二次,down,重复次数1,长按

第三次,up,重复次数0,长按

这三次事件第二次与第一次差500ms,第三次紧接着第二次出现

明白了按键长按状态下会有什么标志就可以选择何时去处理响应,处理哪一个。也可以很好的明白为什么程序里对按键要做那么复杂

的判断----是为了定位到某一次,让满足条件的事件只要一次。


不同的按键也许有不同的action,比如上下键左右键,如果长按的话会一直down,所以在处理之前先要明白按键在长按或者短按情况

下到底是怎么响应的。

在Android源码的按键处理中,一般是这样

  • 短按事件就监听按键的up事件
  • 长按事件就监听按键的down事件

这也很好理解,比如你想长按做一件事,如果长按要响应up事件的话那就表示用户一直长按直到抬起up才会有所响应,这样的话用

户会很迷茫啊,不知道到底该何时抬起,不知道到底有没有响应。所以解决办法就是在用户按下按键的那一刻起即从down开始算,

如果是长按事件并且长按超过了一定时间就去处理。


设计思路就是

长按事件需要有一个固定的长按时间去响应,不受用户长按按键时间的长短影响。

短按事件的话本质上响应down和up都可以,但是因为如果判断条件不多的话有可能down事件来临时机会触发长按和短按两种事件,

所以不如在按键最后一个事件up来的时候再进行处理。

当然如果你的设计有一些特殊的要求,你也可以进行一些设计。


我在设计的时候就遇到了一些问题

问题描述:

假设现在有两个activity,ActivityA和ActivityB,在A界面我需要在长按某个按键时进行一些处理。比如长按menu键跳转至activityB,

在activityB界面有对menu键抬起后的事件的监听。我的做法是在界面A中监听按键的down事件判断是否长按然后进行处理,在处理

结束后返回true,不再往下分发按键事件。这就导致一个现象就是,当我长按menu键跳转至activityB时会触发在B界面的

menu键抬起的事件,可是我只是想对menu键短按抬起做一个处理。


比如上述这个问题,就是对按键的事件不太清楚,一个按键流程分为down和up,虽然你在A界面处理了按键的长按事件,虽然看似

你返回了true,你返回true仅仅表示该按键的down事件你不会往下传递,但是你并没有处理up事件,所以就会导致在界面B响应按键

的up事件。


一般的,在按键处理或者触屏处理事件过程中,如果不想把某个事件分发下去,我们都是直接返回true,表示不分发了。其实逻辑上

这个想法是对的。但你需要把整个按键事件都拦截掉。不能只拦截down事件却不拦截up事件。

其实按键事件和触摸事件很像,如果你不想往下传递某个触摸事件那么你首先要清楚触摸事件都有哪

些?ACTION_DOWN?action_up?action_move??等等,你需要保证你拦截了事件的最后一个action,这样才能真真正正的把事件

给拦截掉。

这是我工作中遇到的问题,幸而有师傅指点,非常感谢~~

你可能感兴趣的:(Android拓展学习)