Cómo controlar las acciones del teclado

Cuando el usuario enfoca una vista de texto editable, como un elemento EditText, y tiene un teclado de hardware conectado, el sistema controla todas las entradas. Sin embargo, si deseas interceptar o manejar directamente la entrada del teclado, puedes hacerlo mediante la implementación de métodos de devolución de llamada desde la interfaz KeyEvent.Callback, como onKeyDown() y onKeyMultiple().

Las clases Activity y View implementan la interfaz KeyEvent.Callback, por lo que, en general, debes anular los métodos de devolución de llamada en tu extensión de estas clases, según corresponda.

Nota: Cuando controlas eventos de teclado con la clase KeyEvent y las APIs relacionadas, espera que los eventos de teclado provengan solo de un teclado de hardware. Nunca confíes en recibir eventos de teclas para ninguna tecla en un método de entrada de software (un teclado en pantalla).

Cómo controlar eventos de una sola tecla

Para controlar cuando se presiona una tecla individual, implementa onKeyDown() o onKeyUp() según corresponda. Por lo general, usas onKeyUp() si deseas asegurarte de recibir un solo evento. Si el usuario mantiene presionada una tecla, se llama a onKeyDown() varias veces.

Por ejemplo, en esta implementación, se responde a algunas teclas del teclado para controlar un juego:

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);
    }
}

Cómo controlar teclas modificadoras

Para responder a eventos de teclas modificadoras, como cuando una tecla se combina con Mayúsculas o Control, puedes consultar el KeyEvent que se pasa al método de devolución de llamada. Varios métodos proporcionan información sobre las teclas modificadoras, como getModifiers() y getMetaState(). Sin embargo, la solución más simple es comprobar si se está presionando la tecla modificadora exacta que te interesa con métodos como isShiftPressed() y isCtrlPressed().

Por ejemplo, aquí se muestra nuevamente la implementación de onKeyUp(), con un control adicional para cuando la tecla Mayúsculas se mantiene presionada con una de las teclas:

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);
    }
}

Recursos adicionales