Target di messa a fuoco del gruppo

Puoi raggruppare più target di messa a fuoco utilizzando il modificatore focusGroup. Il raggruppamento ti consente di gestire le gerarchie di messa a fuoco, isolare le regioni logiche dell'interfaccia utente (come barre degli strumenti, azioni di dialogo o elenchi di schede) e intercettare quando la messa a fuoco entra o esce da una regione.

Concetti relativi ai gruppi di messa a fuoco: ingresso, uscita e spostamento predefinito

Un gruppo di messa a fuoco stabilisce un limite di navigazione coeso intorno ai relativi target di messa a fuoco secondari. Per capire come lo stato attivo si sposta oltre questo confine, è necessario comprendere due concetti chiave:

  • Invio: l'evento che si verifica quando lo stato attivo passa da un elemento al di fuori del gruppo di messa a fuoco a un elemento all'interno del gruppo.
  • Uscita: l'evento che si verifica quando lo stato attivo di selezione esce dall'ultimo elemento interno del gruppo e passa a un target di stato attivo di selezione esterno.
Diagramma che mostra le transizioni di entrata e uscita attraverso il confine di un focus group.
Figura 1. Focus group con eventi di entrata e uscita.

Comportamento predefinito di spostamento del focus

Per impostazione predefinita, quando un focus group riceve la messa a fuoco dall'esterno:

  1. Inserimento del gruppo: Compose seleziona automaticamente un target di messa a fuoco secondario interno. Per la navigazione unidimensionale (scheda), seleziona il primo elemento secondario in ordine di aspetto visivo. Per la navigazione bidimensionale (tasto freccia o D-pad), seleziona l'elemento figlio geometricamente più vicino alla direzione in arrivo.
  2. Navigazione all'interno del gruppo: le pressioni ripetute dei tasti di navigazione spostano lo stato attivo tra i target attivi di pari livello racchiusi nel gruppo.
  3. Uscita dal gruppo: una volta che l'utente ha superato l'ultimo target di messa a fuoco all'interno del gruppo, la pressione del tasto successivo esce dal gruppo e sposta lo stato attivo sul target di messa a fuoco adiacente all'esterno del gruppo.

Personalizzare il reindirizzamento delle voci di selezione

In molti design dell'interfaccia utente, il target di inserimento predefinito (ad esempio il primo elemento secondario in ordine di visualizzazione) non è la scelta più logica o conveniente per l'utente.

Intenzione e casi d'uso

Prendi in considerazione una finestra di dialogo di conferma con un pulsante "Annulla" a sinistra e un pulsante "Conferma" principale a destra. Quando l'utente naviga verso il basso nella barra dei pulsanti da un campo del modulo:

  • Comportamento predefinito: il focus si sposta su "Annulla" perché è il primo pulsante nell'ordine di visualizzazione.
  • Comportamento previsto: poiché "Conferma" è l'azione principale consigliata, potresti voler fare in modo che lo stato attivo si sposti direttamente su "Conferma" quando entri nel gruppo di pulsanti dall'inizio dell'ordine di messa a fuoco, consentendo comunque all'utente di premere Freccia sinistra per selezionare "Annulla" se necessario.
Voce di stato attivo predefinita in un gruppo di pulsanti.
Figura 2. Pulsanti Annulla e Conferma con target di immissione della messa a fuoco predefinito.

Altri casi d'uso comuni includono:

  • Spostamento dello stato attivo di selezione direttamente sulla scheda attualmente selezionata quando viene inserito un TabRow.
  • Spostamento dello stato attivo direttamente sul controllo "Riproduci / Metti in pausa" quando si accede a una barra di riproduzione multimediale.

Implementazione con onEnter e FocusRequester

Per reindirizzare lo stato attivo quando entri in un focus group:

  1. Applica il modificatore focusGroup al contenitore principale che racchiude i target di messa a fuoco correlati.
  2. Applica il modificatore focusProperties al contenitore e configura il callback onEnter.
  3. Nel callback onEnter (ambito di FocusEnterExitScope), chiama requestFocus() su un intent FocusRequester associato al preferito figlio predefinito utilizzando focusRequester.

val defaultChildRequester = remember { FocusRequester() }

Row(
    modifier = Modifier
        .focusGroup()
        .focusProperties {
            // Intercept entry into this group and redirect focus to the primary action
            onEnter = {
                defaultChildRequester.requestFocus()
            }
        }
) {
    Button(onClick = { /* Cancel action */ }) {
        Text("Cancel")
    }
    Button(
        onClick = { /* Confirm action */ },
        modifier = Modifier.focusRequester(defaultChildRequester)
    ) {
        Text("Confirm (Default)")
    }
}

All'interno di onEnter e onExit, puoi anche chiamare cancelFocusChange() per bloccare completamente le transizioni del focus oltre il confine o ispezionare requestedFocusDirection per personalizzare il routing in base al metodo di navigazione dell'utente: Tab, Freccia giù o Freccia sinistra.

I contenitori scorrevoli sono gruppi di messa a fuoco per impostazione predefinita

In Jetpack Compose, i contenitori scorrevoli come LazyRow, LazyColumn e LazyVerticalGrid fungono automaticamente da gruppi di messa a fuoco. Non è necessario applicare esplicitamente il modificatore focusGroup per impostare i callback onEnter o onExit.