Ao navegar por interfaces do usuário complexas usando um teclado físico ou um botão direcional, os usuários costumam se mover entre diferentes seções da tela, como pular de uma coluna de navegação lateral para uma lista de conteúdo, interagir com um item e voltar. A restauração do foco permite que os contêineres se lembrem do elemento filho em foco anteriormente e restaurem o foco para ele quando o foco entrar 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 de 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 lento, 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 de 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 filho focado anteriormente. O Compose segue a ordem de foco padrão para determinar em qual elemento filho focar.
É possível personalizar qual filho recebe o foco na primeira entrada transmitindo um
FocusRequester substituto 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 anteriormente (ou se a restauração do foco falhar), o Compose vai mover o foco para o destino substituto associado.
Foco direto no 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 retorna usando o botão "Voltar" ou gesto, é possível restaurar o foco para o 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 para a tela, solicite o foco inicial no
contêiner ou chame
restoreFocusedChild().
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Metas de foco
- Ordem de apresentação do foco
- Agrupar alvos de foco
- Solicitar foco de forma programática
- Mover e limpar o foco