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 maneja todas las entradas. Sin embargo, si quieres interceptar la entrada del teclado o controlarla directamente, 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, por lo general, anulas los métodos de devolución de llamada en tu extensión de estas clases, según corresponda.

Nota: Cuando controles eventos de teclado con la clase KeyEvent y las APIs relacionadas, se espera que los eventos de teclado provengan solo de un teclado de hardware. Nunca dependas de la recepción de 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 cómo se presiona una tecla individual, implementa onKeyDown() o onKeyUp(), según corresponda. Por lo general, debes usar onKeyUp() si deseas asegurarte de recibir solo un 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 verificar si se presiona la tecla modificadora exacta que te interesa con métodos como isShiftPressed() y isCtrlPressed().

Por ejemplo, esta es la implementación de onKeyUp() otra vez, con 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