美文网首页
AndroidTV开发 输入键位总结

AndroidTV开发 输入键位总结

作者: _惊蛰 | 来源:发表于2020-11-21 14:42 被阅读0次

    输入设备的按键事件,在Android设备中会被转换为KeyEvent对象。而游戏手柄中的摇杆则会产生对应的MotionEvent对象。

    关于事件分发机制

    先大概看下事件的分发机制。简单来说,比如按键事件,分发按键事件的方法叫 dispatchKeyEvent()

    一个事件首先被顶层DecorView分发给Activity,然后Activity会调用 dispatchKeyEvent() 方法将事件分发给ViewGroup层,在经过层层传递后,最终事件会到达我们想接受事件的View。View接受到事件后也会调用自己的 dispatchKeyEvent() 方法,然后就开始处理事件。默认情况下,会首先查看是否有给View设 OnKeyListener 。如果没有,或者有但是返回结果为false,那么事件还会继续交给View的 onKeyDown() onKeyUp() 等方法。如果为true,则事件立刻被消耗掉,后面不会再给其他方法了。其次,在交给 ViewonKeyDown()onKeyUp()方法后,如果这些方法又返回了false,那么事件不会被消耗掉,会进一步交给上层,最终在Activity的 onKeyDown() onKeyUp()方法中处理。而如果返回了true,则事件被消耗掉,事件处理就此结束。

    监听事件

    对于按键事件,有以下方法可以来处理

    onKeyDown() : 按键按下

    onKeyUp() : 按下之后松开

    onKeyLongPress():长按

    onKeyMultiple():多次重复事件

    onKeyShortCut():快捷键事件

    在长按的时候,首先会调 onKeyDown(),然后一般会连续调用onKeyDown()多次,或在调两次之后直接调用一次onKeyLongPress()方法一次就停止,这个可能与输入设备和按键有关。

    不过,如果是要在Webview中监听按键事件,因为给Webview loadurl之后,KeyEvent就被消耗了,重写onKeyDown()等方法是接收不到事件的。所以还是建议直接重写 dispatchKeyEvent() 方法,这样可以从一开始就截获事件,不必担心不必要的麻烦。

    对于游戏手柄中的摇杆事件,可以通过重写 dispatchGenericMotionEvent 方法来监听。

    事件对象

    事件对象,包括按键事件 KeyEvent和摇杆事件MotionEvent

    KeyEvent

    一个KeyEvent对象,有以下属性:

    action : 按键的动作。有DOWN UP等
    keyCode : 按键代码,跟前面单独的KeyCode一样
    scanCode : 按键事件的原始设备扫描码,最终会转换为keyCode
    metaState : 当前按键的metaState
    flags : 当前按键事件的flags
    repeatCount : 按键事件重复的次数。有的按键在长按的时候,会连续产生多个DOWN事件,这个时候除第一个DOWN事件的repeatCount为0,之后的DOWN事件的repeatCount会递增。之所以是部分按键,是因为我发现键盘上的按键长按时,会被识别为 DOWN UP DOWN UP序列,而长按比如手机的虚拟按键时,事件序列是 DOWN DOWN UP
    eventTime : 这个事件发生的时间,是一个从开机到现在的毫秒数。
    downTime : 这个按键按下的时间,是一个从开机到现在的毫秒数。如果同一个按键先按下再弹起,那么他有两个事件,UP和DOWN,且这两个事件的downTime是一样的
    deviceId : 产生按键事件的设备deviceid
    source : 输入源,具体可以参考 InputDevice类

    这里keyCode有很多,除了基础的Android手机的几个虚拟按键外,还有整个键盘按键、游戏手柄按键、电视遥控器等,具体在官网有讲,也有一些靠谱的翻译:

    官方文档
    翻译

    摇杆事件

    一个MotionEvent对象,表示摇杆相关状态,常用的一些值,需要用 getAxisValue()方法通过传入不同的参数来获取当前值,此外有一些类似方法可以获取历史值。

    AXIS_X参数,获取到x值,表示水平方向移动距离,向右为正,向左为负
    AXIS_Y参数,获取到y值,表示垂直方向移动距离,向下为正,向上为负
    AXIS_Z参数,获取到z值,表示水平方向移动距离,向右为正,向左为负
    AXIS_RZ参数,获取到rz值,表示垂直方向移动距离,向下为正,向上为负
    AXIS_BRAKE参数,获取到break值,表示肩键状态,1为按住 0为释放
    AXIS_GAS参数,获取到gas值,表示肩键状态,1为按住 0为释放负

    官方文档
    翻译

    键位映射

    键盘

    在接入键盘时,每个按键在按下、弹起时都有对应的 KeyEvent 对象,对应着一个事件,可以使用。

    手柄

    在接入手柄时,有两种事件,分别是按键事件 KeyEvent和移动事件MotionEvent

    手柄中的常规按键,都会对应一个或多个 KeyEvent,而操作摇杆时,或者按下左右侧的L2 R2键时,会产生MotionEvent。其中按键事件不一定是一对一的,部分键是一次操作有多种按键事件。而移动事件可以获取当前摇杆的移动情况,用坐标形式来模拟,具体映射如下:

    X : 按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_XKEYCODE_DEL。长按会继续产生 KEYCODE_DEL 按键事件。
    Y : 按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_YKEYCODE_SPACE。长按会继续产生 KEYCODE_SPACE 按键事件。
    A : 按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_AKEYCODE_DPAD_CENTER。长按会继续产生 KEYCODE_DPAD_CENTER 按键事件。
    B : 按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_BKEYCODE_BACK。长按会继续产生 KEYCODE_BACK 按键事件。

    ↑ : 按下会先产生一个摇杆事件,坐标移动量为0。之后会产生一个按键事件,对应 KeyCodeKEYCODE_DPAD_UP。如果是长按,则会继续产生相同的按键事件,直到松开。
    ↓ : 按下会先产生一个摇杆事件,坐标移动量为0。之后会产生一个按键事件,对应 KeyCodeKEYCODE_DPAD_DOWN。如果是长按,则会继续产生相同的按键事件,直到松开。
    ← : 按下会先产生一个摇杆动事件,坐标移动量为0。之后会产生一个按键事件,对应 KeyCodeKEYCODE_DPAD_LEFT。如果是长按,则会继续产生相同的按键事件,直到松开。
    → : 按下会先产生一个摇杆事件,坐标移动量为0。之后会产生一个按键事件,对应 KeyCodeKEYCODE_DPAD_RIGHT。如果是长按,则会继续产生相同的按键事件,直到松开。

    L1 : 按下会产生一个按键事件,对应 KeyCodeKEYCODE_BUTTON_L1,长按继续产生相同事件。
    R1 : 按下会产生一个按键事件,对应 KeyCodeKEYCODE_BUTTON_L2,长按继续产生相同事件。

    L2 : 按下会产生一个按键事件,对应 KeyCodeKEYCODE_BUTTON_L2,之后再产生一个摇杆事件,坐标移动量为0。长按继续产生相同的按键事件。松开后坐标移动量中 break 会变为1

    R2 : 按下会产生一个按键事件,对应 KeyCodeKEYCODE_BUTTON_R2,之后再产生一个移动事件,坐标移动量为0。长按继续产生相同的按键事件。松开后坐标移动量中 gas 会变为1。

    左摇杆 :按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_THUMBLKEYCODE_DPAD_CENTER。长按会继续产生 KEYCODE_DPAD_CENTER 按键事件。拨动摇杆时,会连续产生多个移动事件。移动事件的x y值表示当前拨动的距离。

    右摇杆 :按下一次会产生两个按键事件,对应的 KeyCode 依次为 KEYCODE_BUTTON_THUMBLKEYCODE_DPAD_CENTER。长按会继续产生 KEYCODE_DPAD_CENTER 按键事件。拨动摇杆时,会连续产生多个移动事件。移动事件的z zr值表示当前拨动的距离。

    手柄的适配情况,在主流的Xbox360类手柄上是完全适配的,Switch Pro类手柄的L2 R2键没有KeyEvent事件

    相关文章

      网友评论

          本文标题:AndroidTV开发 输入键位总结

          本文链接:https://www.haomeiwen.com/subject/hpfeiktx.html