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 quieres interceptar o controlar directamente la entrada del teclado, puedes hacerlo mediante la implementación de métodos de devolución de llamada de la interfaz KeyEvent.Callback, como onKeyDown() y onKeyMultiple().

Las clases Activity y View implementan la interfaz KeyEvent.Callback, por lo que, en 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, debes esperar que los eventos del teclado provengan solo de un teclado de hardware. No dependas nunca de 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 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 comprobar si se está presionando la tecla modificadora exacta que te interesa con métodos como isShiftPressed() y isCtrlPressed().

Por ejemplo, esta es una vez más la implementación de onKeyUp(), 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);
    }
}