Quando os usuários navegam em interfaces complexas usando um teclado físico ou um botão direcional, eles costumam se mover entre diferentes seções da tela, como pular de uma barra de navegação lateral para uma lista de conteúdo, interagir com um item e voltar. Com a restauração do foco, os contêineres lembram o elemento filho em foco anteriormente e restauram o foco nele quando ele entra novamente no contêiner.
Restaurar o foco em contêineres roláveis
No Jetpack Compose, contêineres roláveis, como LazyColumn, LazyRow e LazyVerticalGrid, atuam automaticamente como grupos de foco. Para ativar a restauração do foco em uma lista ou grade lenta, anexe o modificador focusRestorer:
LazyColumn( modifier = Modifier.focusRestorer() ) { items(items) { item -> Button(onClick = { /* Handle click */ }) { Text(item) } } }
Quando o foco sai do LazyColumn, o contêiner registra qual item estava ativo.
Quando o usuário volta para a lista, o foco é restaurado para esse item em vez de reiniciar na parte de cima.
Restaurar o foco em Row e Column
Ao contrário dos contêineres de layout lazy, os contêineres de layout padrão não roláveis, como
Row e Column, não estabelecem um limite de foco por padrão.
Como eles não interceptam eventos de entrada de foco por conta própria, aplicar apenas o modificador focusRestorer não é suficiente.
Para ativar a restauração do foco em Row ou Column, combine focusGroup com
focusRestorer:
Row( modifier = Modifier .focusGroup() .focusRestorer() ) { Button(onClick = { /* Action 1 */ }) { Text("First item") } Button(onClick = { /* Action 2 */ }) { Text("Second item") } Button(onClick = { /* Action 3 */ }) { Text("Third item") } }
Especificar um destino de foco substituto
Quando o foco entra em um contêiner pela primeira vez, não há um elemento filho focado anteriormente. O Compose segue a ordem de foco padrão para determinar qual filho focar.
Você pode personalizar qual elemento filho recebe o foco na primeira entrada transmitindo um
FocusRequester de substituição para focusRestorer (ou uma lambda que retorna um
FocusRequester em versões anteriores do Compose):
val firstItemRequester = remember { FocusRequester() } LazyColumn( modifier = Modifier.focusRestorer(firstItemRequester) ) { itemsIndexed(items) { index, item -> val itemModifier = if (index == 0) { Modifier.focusRequester(firstItemRequester) } else { Modifier } Button( onClick = { /* Handle click */ }, modifier = itemModifier ) { Text(item) } } }
Se nenhum filho tiver sido focado antes ou se a restauração do foco falhar, o Compose move o foco para o destino de substituição associado.
Direcionar o foco para o item selecionado nos componentes de navegação
Em componentes de navegação, como NavigationRail, NavigationBar, NavigationDrawer ou TabRow, os usuários esperam que o foco seja direcionado ao
destino selecionado ao entrar no componente pela área de
conteúdo.
É possível direcionar o foco para o destino ativo combinando
Modifier.focusGroup() com focusProperties e definindo a propriedade onEnter (ou enter em versões anteriores do Compose):
val (homeRequester, searchRequester, settingsRequester) = remember { FocusRequester.createRefs() } val selectedRequester = when (currentDestination) { "home" -> homeRequester "search" -> searchRequester "settings" -> settingsRequester else -> homeRequester } NavigationRail( modifier = modifier .focusProperties { // Redirect focus to the selected item when focus enters the navigation rail onEnter = { selectedRequester.requestFocus() } } .focusGroup() ) { NavigationRailItem( selected = currentDestination == "home", onClick = { onNavigate("home") }, icon = { Icon(Icons.Default.Home, contentDescription = "Home") }, label = { Text("Home") }, modifier = Modifier.focusRequester(homeRequester) ) NavigationRailItem( selected = currentDestination == "search", onClick = { onNavigate("search") }, icon = { Icon(Icons.Default.Search, contentDescription = "Search") }, label = { Text("Search") }, modifier = Modifier.focusRequester(searchRequester) ) NavigationRailItem( selected = currentDestination == "settings", onClick = { onNavigate("settings") }, icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") }, label = { Text("Settings") }, modifier = Modifier.focusRequester(settingsRequester) ) }
Restaurar o foco nas transições de tela
Quando um usuário clica em um item para navegar até uma tela de detalhes e depois volta usando o botão "Voltar" ou gesto, é possível restaurar o foco no item em que ele clicou.
Para preservar e restaurar o foco nas transições de tela:
- Associe o contêiner a um
FocusRequester. - Antes de acionar o evento de navegação, chame
saveFocusedChild()noFocusRequesterdo contêiner. - Quando o usuário voltar à tela, solicite o foco inicial no
container ou chame
restoreFocusedChild().
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Segmentações por foco
- Ordem de apresentação do foco
- Agrupar alvos de foco
- Solicitar o foco de maneira programática
- Mover e limpar o foco