Cuando el usuario enfoca un componente de texto editable, como un TextField, y el dispositivo tiene un teclado de hardware conectado, el sistema controla todas las entradas.
Puedes proporcionar combinaciones de teclas controlando eventos de tecla.
Combinaciones de teclas predeterminadas
Las siguientes combinaciones de teclas están disponibles de forma predeterminada.
| Combinación de teclas | Acción | Elementos componibles que admiten la combinación de teclas |
|---|---|---|
| Mayúsculas+Ctrl+flecha hacia la izquierda/flecha hacia la derecha | Seleccionar el texto hasta el principio o final de la palabra | BasicTextField, TextField |
| Mayúsculas+Ctrl+Flecha hacia arriba/Flecha hacia abajo | Seleccionar el texto hasta el principio o final del párrafo | BasicTextField, TextField |
| Mayúsculas+Alt+flecha hacia arriba/flecha hacia abajo o Mayúsculas+Meta+flecha hacia la izquierda/flecha hacia la derecha | Seleccionar el texto hasta el principio o final del texto | BasicTextField, TextField |
| Mayúsculas+flecha hacia la izquierda/flecha hacia la derecha | Selecciona los personajes | BasicTextField, TextField |
| Ctrl + A | Seleccionar todo | BasicTextField, TextField |
| Ctrl + C/Ctrl + X/Ctrl + V | Copiar, cortar y pegar | BasicTextField, TextField |
| Ctrl + Z/Ctrl + Mayúsculas + Z | Deshacer/Rehacer | BasicTextField, TextField |
| PageDown/PageUp | Desplazamiento | LazyColumn, el modificador verticalScroll y el modificador scrollable |
Eventos clave
En Compose, puedes controlar una pulsación de tecla individual con el modificador onKeyEvent.
El modificador acepta una expresión lambda a la que se llama cuando el componente modificado recibe un evento de tecla.
Un evento de tecla se describe como un objeto KeyEvent.
Puedes obtener la información de cada evento de tecla haciendo referencia al objeto en la expresión lambda que se pasa al modificador onKeyEvent.
Una pulsación de tecla envía dos eventos de tecla.
Uno se activa cuando el usuario presiona la tecla y el otro, cuando la suelta.
Puedes distinguir los dos eventos clave haciendo referencia al atributo type del objeto KeyEvent.
El valor que se muestra de la expresión lambda onKeyEvent indica si se controla el evento de tecla o no.
Muestra true si tu app controla el evento de tecla, lo que detiene la propagación del evento.
En el siguiente fragmento, se muestra cómo llamar a una función doSomething() cuando el usuario suelta la tecla S en el componente Box:
Box( modifier = Modifier .onKeyEvent { if ( it.type == KeyEventType.KeyUp && it.key == Key.S ) { doSomething() true } else { false } } .focusable() ) { Text("Press S key") }
Teclas modificadoras
Un objeto KeyEvent tiene los siguientes atributos que indican si se presionan o no las teclas modificadoras:
Sé específico cuando describas los eventos de teclas que controla tu app.
En el siguiente fragmento, se llama a una función doSomething() solo si el usuario suelta la tecla S.
Si el usuario presiona cualquier tecla modificadora, como la tecla Mayúsculas, la app no llama a la función.
Box( modifier = Modifier .focusable() .onKeyEvent { if ( it.type == KeyEventType.KeyUp && it.key == Key.S && !it.isAltPressed && !it.isCtrlPressed && !it.isMetaPressed && !it.isShiftPressed ) { doSomething() true } else { false } } ) { Text("Press S key with a modifier key") }
Eventos de clic de la barra espaciadora y la tecla Intro
La barra espaciadora y la tecla Intro también activan eventos de clic. Por ejemplo, los usuarios pueden activar o desactivar (reproducir o pausar) la reproducción de contenido multimedia con la barra espaciadora o la tecla Intro controlando los eventos de clic de la siguiente manera:
MediaPlayer(modifier = Modifier.clickable { togglePausePlay() })
El modificador clickable intercepta los eventos de teclas y llama a la devolución de llamada onClick() cuando se presiona la barra espaciadora o la tecla Intro.
Por eso, se llama a la función togglePausePlay() presionando la barra espaciadora o la tecla Intro en el fragmento.
Eventos clave no consumidos
Los eventos de tecla no consumidos se propagan desde el componente en el que se produjo el evento hasta el componente externo que lo contiene.
En el siguiente ejemplo, el InnerComponent consume eventos de teclas cuando se suelta la tecla S, por lo que el OuterComponent no recibe ningún evento de tecla que se active cuando se suelta la tecla S.
Por eso, nunca se llama a la función actionB().
Otros eventos de tecla en InnerComponent, como soltar la tecla D, se pueden controlar con OuterComponent.
Se llama a la función actionC() porque el evento de tecla para soltar la tecla D se propaga a OuterComponent.
OuterComponent( modifier = Modifier.onKeyEvent { when { it.type == KeyEventType.KeyUp && it.key == Key.S -> { actionB() // This function is never called. true } it.type == KeyEventType.KeyUp && it.key == Key.D -> { actionC() true } else -> false } } ) { InnerComponent( modifier = Modifier.onKeyEvent { if (it.type == KeyEventType.KeyUp && it.key == Key.S) { actionA() true } else { false } } ) }
Modificador onKeyPreviewEvent
En algunos casos de uso, es posible que quieras interceptar un evento de tecla antes de que active la acción predeterminada.
Un ejemplo típico es agregar combinaciones de teclas personalizadas a un TextField.
El siguiente fragmento permite que los usuarios pasen al siguiente componente enfocable presionando la tecla Tab.
val focusManager = LocalFocusManager.current var textFieldValue by remember { mutableStateOf(TextFieldValue()) } TextField( textFieldValue, onValueChange = { textFieldValue = it }, modifier = Modifier.onPreviewKeyEvent { if (it.type == KeyEventType.KeyUp && it.key == Key.Tab) { focusManager.moveFocus(FocusDirection.Next) true } else { false } } )
De forma predeterminada, el componente TextField agrega un carácter de tabulación cada vez que los usuarios presionan la tecla Tab, incluso si el evento de tecla se controla con el modificador onKeyEvent.
Para mover el enfoque del teclado sin agregar caracteres de tabulación, controla el evento de tecla antes de activar las acciones asociadas con el evento de tecla, como en el fragmento.
La expresión lambda onKeyPreviewEvent() intercepta el evento de tecla devolviendo true.
El componente superior puede interceptar el evento de tecla que ocurre en sus elementos secundarios.
En el siguiente fragmento, se llama a la función previewSKey() cuando los usuarios presionan la tecla S, en lugar de llamar a la función actionForPreview().
Column( modifier = Modifier.onPreviewKeyEvent { if (it.key == Key.S) { previewSKey() true } else { false } } ) { Box( modifier = Modifier .focusable() .onPreviewKeyEvent { actionForPreview(it) false } .onKeyEvent { actionForKeyEvent(it) true } ) { Text("Press any key") } }
La expresión lambda onPreviewKeyEvent() del componente Box tampoco se activa cuando los usuarios presionan la tecla Tab.
Primero, se llama a la lambda onPreviewKeyEvent() en el componente superior y, luego, se llama a onPreviewKeyEvent() en el componente secundario.
Puedes implementar combinaciones de teclas para toda la pantalla con este comportamiento.
Recursos adicionales
- Ayuda en las combinaciones de teclas: Es la pantalla del sistema que permite a los usuarios buscar las combinaciones de teclas que ofrece tu app.