1、简介
本文逻辑流程图基于Android 8.0,其他版本可能略有不同但是主体流程是一样的。
KeyEvent的分发是从Activity->ViewGroup->View。
2、KeyEvent的组成
KeyEvent的主要包含两个部分:action和键值
- action
Action_down或者Action_up,代表是按下或者抬起 - 键值
比如数字键、确定键等
3、KeyEvent常用方法
- getAction() // 获取action的值判断是按下和抬起
- getKeyCode()//获取按键的键值
- getRepeatCount()//获取event重复的数量
只会在ACTION为ACTION_DOWN的有意义,就是按下,,值为0代表第一次按,其他值计算时间可以认为是长按
4、KeyEvent事件序列
一个KeyEvent的触发的Action的序列是 Acttion_down…Acttion_down…Action_up
从action_down开始然后可能有多个action_down(长按时)和一个action_up(抬起)
5、KeyEvent的分发逻辑图
注意:
-
DecorView调用dispatchKeyEvent分发KeyEvent给Activity
-
Activity调用dispatchKeyEvent往view层级进行分发,Activity的dispatchKeyEvent不管返回true/false都交给了DecorView去处理
-
ViewGroup优先拿到KeyEvent,然后调用dispatchKeyEvent往子View分发,如果ViewGroup dispatchKeyEvent的返回false则交给Activity去处理,Activity的onKeyDown、onKeyup和 onKeyLongPress方法会相应触发。如果ViewGroup自身获取了焦点,则优先自己去处理,不往子View去分发
-
View拿到KeyEvent继续分发首先触发onKeyListener,如果此监听器消费了就结束了,如果不消费会去触发View的onKeyDown、onKeyup、onKeyLongPress和onKeyLongClick相应方法会触发
-
onKeyListener的优先级比onKeyDown和onKeyup和onKeyLongPress优先级高
-
onKeyLongPress 按键长按回调触发的前提是某个按键值第一次调用onKeyDown的返回值必须为true,就是按键第一个ACTION_DOWN的处理必须为true,表示消费此按键按下事件。默认情况下 系统处理了认为是确定的键值,如以下:
public static final boolean isConfirmKey(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_SPACE:
case KeyEvent.KEYCODE_NUMPAD_ENTER:
return true;
default:
return false;
}
}
也就是如果按了是确认的键值,是可以触发onKeyLongPress的,其他的按键如果需要响应,需要重写onKeyDown方法并且返回true。
- onKeyLongClickListener长按点击事件,默认情况下是响应系统认为是确认键的键值的。