处理键盘操作

当用户将焦点转移到可修改的文本视图(例如 EditText 元素),并且连接了硬件键盘时,所有输入均由系统处理。不过,如果您想要拦截或直接自行处理键盘输入,则可以通过从 KeyEvent.Callback 接口中实现回调方法(例如 onKeyDown()onKeyMultiple())来实现此目的。

Activity 类和 View 类都会实现 KeyEvent.Callback 接口,因此您通常应该视情况在这些类的子类中替换这些回调方法。

注意:在使用 KeyEvent 类和相关 API 处理键盘事件时,您应该会发现硬件键盘是此类键盘事件的唯一来源。您绝不能依赖于接收软输入法(屏幕键盘)中的任何按键对应的按键事件。

处理单个按键事件

要处理单个按键操作,请视情况实现 onKeyDown()onKeyUp()。通常,如果您想要确保只接收一个事件,则应该使用 onKeyUp()。如果用户按住按钮,则系统会多次调用 onKeyDown()

例如,以下实现可以响应某些键盘按键以控制游戏:

Kotlin

    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            KeyEvent.KEYCODE_D -> {
                moveShip(MOVE_LEFT)
                true
            }
            KeyEvent.KEYCODE_F -> {
                moveShip(MOVE_RIGHT)
                true
            }
            KeyEvent.KEYCODE_J -> {
                fireMachineGun()
                true
            }
            KeyEvent.KEYCODE_K -> {
                fireMissile()
                true
            }
            else -> super.onKeyUp(keyCode, event)
        }
    }
    

Java

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_D:
                moveShip(MOVE_LEFT);
                return true;
            case KeyEvent.KEYCODE_F:
                moveShip(MOVE_RIGHT);
                return true;
            case KeyEvent.KEYCODE_J:
                fireMachineGun();
                return true;
            case KeyEvent.KEYCODE_K:
                fireMissile();
                return true;
            default:
                return super.onKeyUp(keyCode, event);
        }
    }
    

处理辅助键

要响应辅助键事件(例如,某个按键与 Shift 键或 Control 键结合使用),则可以查询传递给回调方法的 KeyEvent。有几种方法可以提供有关辅助键的信息,例如 getModifiers()getMetaState()。不过,最简单的解决方案是使用 isShiftPressed()isCtrlPressed() 等方法检查您关注的确切辅助键是否已被按下。

例如,以下还是 onKeyDown() 实现,以及在 Shift 键与某个按键同时按住时需要进行的一些额外处理:

Kotlin

    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            ...
            KeyEvent.KEYCODE_J -> {
                if (event.isShiftPressed) {
                    fireLaser()
                } else {
                    fireMachineGun()
                }
                true
            }
            KeyEvent.KEYCODE_K -> {
                if (event.isShiftPressed) {
                    fireSeekingMissle()
                } else {
                    fireMissile()
                }
                true
            }
            else -> super.onKeyUp(keyCode, event)
        }
    }
    

Java

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
            ...
            case KeyEvent.KEYCODE_J:
                if (event.isShiftPressed()) {
                    fireLaser();
                } else {
                    fireMachineGun();
                }
                return true;
            case KeyEvent.KEYCODE_K:
                if (event.isShiftPressed()) {
                    fireSeekingMissle();
                } else {
                    fireMissile();
                }
                return true;
            default:
                return super.onKeyUp(keyCode, event);
        }
    }