Quando o usuário dá foco a um componente de texto editável, como um TextField,
e o dispositivo tem um teclado físico conectado,
toda a entrada é processada pelo sistema.
Você pode fornecer atalhos do teclado processando eventos de tecla.
Atalhos de teclado padrão
Os atalhos de teclado a seguir já estão disponíveis.
| Atalho do teclado | Ação | Elementos combináveis com suporte ao atalho |
|---|---|---|
| Shift+Ctrl+seta para a esquerda/seta para a direita | Selecionar o texto até o início/fim da palavra | BasicTextField, TextField |
| Shift+Ctrl+Seta para cima/Seta para baixo | Selecionar o texto até o início/fim do parágrafo | BasicTextField, TextField |
| Shift+Alt+seta para cima/seta para baixo ou Shift+Meta+seta para a esquerda/seta para a direita | Selecionar o texto até o início/fim do texto | BasicTextField, TextField |
| Shift + seta para a esquerda/seta para a direita | Selecionar caracteres | BasicTextField, TextField |
| Ctrl+A | Selecionar tudo | BasicTextField, TextField |
| Ctrl+C/Ctrl+X/Ctrl+V | Copiar/recortar/colar | BasicTextField, TextField |
| Ctrl+Z/Ctrl+Shift+Z | Desfazer/refazer | BasicTextField, TextField |
| PageDown/PageUp | Rolagem | LazyColumn, o modificador verticalScroll, o modificador scrollable |
Eventos principais
No Compose, é possível processar uma tecla individual com
o modificador onKeyEvent.
O modificador aceita uma lambda chamada
quando o componente modificado recebe um evento de tecla.
Um evento principal é descrito como um objeto KeyEvent.
Para ver as informações de cada evento principal, consulte o objeto
na lambda transmitida ao modificador onKeyEvent.
Um pressionamento de tecla envia dois eventos de tecla.
Um é acionado quando o usuário pressiona a tecla.
o outro é acionado quando a chave é liberada.
É possível diferenciar os dois eventos principais
consultando o atributo type do objeto KeyEvent.
O valor de retorno da lambda onKeyEvent indica
se o evento de tecla é tratado ou não.
Retorne true se o app processar o evento de tecla.
que interrompe a propagação do evento.
O snippet a seguir mostra como chamar uma função doSomething()
quando o usuário libera a tecla S no componente Box:
Box(
modifier = Modifier.focusable().onKeyEvent {
if(
it.type == KeyEventType.KeyUp &&
it.key == Key.S
) {
doSomething()
true
} else {
false
}
}
) {
Text("Press S key")
}
Teclas modificadoras
Um objeto KeyEvent tem os seguintes atributos, que indicam
se as teclas modificadoras estão pressionadas ou não:
Descreva de maneira específica os eventos principais processados pelo app.
O snippet a seguir chama uma função doSomething()
somente se o usuário soltar apenas a tecla S.
Se o usuário pressionar qualquer tecla modificadora,
como a tecla Shift, o app não vai chamar a função.
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 clique da tecla "Enter" e da barra de espaço
A barra de espaço e a tecla Enter também acionam eventos de clique. Por exemplo, os usuários podem alternar (reproduzir ou pausar) a reprodução de mídia com a barra de espaço ou a tecla Enter ao processar eventos de clique da seguinte maneira:
MoviePlayer(
modifier = Modifier.clickable { togglePausePlay() }
)
O modificador clickable intercepta eventos de tecla
e chama o callback onClick() quando a tecla Spacebar ou
Enter é pressionada.
É por isso que a função togglePausePlay() é chamada
pressionando a barra de espaço ou a tecla Enter no snippet.
Eventos principais não consumidos
Os eventos principais não consumidos são propagados para o componente
onde o evento ocorreu ao componente externo que o contém.
No exemplo abaixo, o InnerComponent consome eventos principais
quando a chave S é liberada.
Assim, o OuterComponent não recebe nenhum evento principal acionado
ao liberar a chave S.
É por isso que a função actionB() nunca é chamada.
Outros eventos de tecla em InnerComponent, como a liberação da tecla D,
podem ser processados pelo OuterComponent.
A função actionC() é chamada porque o evento de tecla para
liberar a tecla D é propagado para o 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
Em alguns casos de uso, você quer interceptar um evento de tecla
antes de acionar a ação padrão.
Adicionar atalhos personalizados a um TextField é muito comum.
O snippet a seguir permite que os usuários passem para o próximo componente com foco
pressionando a 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
}
}
)
Por padrão, o componente TextField adiciona um caractere de tabulação
sempre que os usuários pressionam a tecla Tab,
mesmo que o evento de tecla seja processado com o modificador onKeyEvent.
Para mover o foco do teclado sem adicionar caracteres de tabulação,
processe o evento de tecla
antes de acionar as ações associadas a ele, como no snippet.
A lambda onKeyPreviewEvent() intercepta o evento de tecla
retornando true.
O componente pai pode interceptar o evento de tecla que acontece nos filhos.
No snippet abaixo, a função previewSKey() é chamada
quando os usuários pressionam a tecla S,
em vez de chamar a função 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")
}
}
O lambda onPreviewKeyEvent() do componente Box também não é acionado
quando os usuários pressionam a tecla Tab.
A lambda onPreviewKeyEvent() é chamada primeiro no componente pai.
então, onPreviewKeyEvent() no componente filho é chamado.
Use esse comportamento para implementar atalhos de teclado na tela inteira.
Outros recursos
- Auxiliar de atalhos do teclado: tela do sistema que permite que os usuários pesquisem os atalhos do teclado oferecidos pelo app.