Manchmal ist es erforderlich, das Standardfokusverhalten der Elemente außer Kraft zu setzen. auf deinem Bildschirm. Sie können beispielsweise zusammensetzbare Funktionen gruppieren, verhindern, Sie legen den Fokus auf eine bestimmte zusammensetzbare Funktion, bitten Sie sich explizit auf eine Funktion, Fokus erfassen oder freigeben oder Fokus auf Ein- oder Ausstieg weiterleiten Dieses wird beschrieben, wie du den Fokus ändern kannst, wenn die Standardeinstellungen nicht deinen Einstellungen entsprechen. die Sie brauchen.
Kohärente Navigation mit Fokusgruppen
Manchmal errät Jetpack Compose nicht sofort das richtige nächste Element für
Navigation mit Tabs, insbesondere wenn komplexe übergeordnete Composables
wie Tabs und
ins Spiel.
Während die Fokussuche normalerweise der Deklarationsreihenfolge von Composables
folgt,
ist dies in manchen Fällen nicht möglich, z. B. wenn einer der Composables
im
ist ein horizontal scrollbares Element,
das nicht vollständig sichtbar ist. Dies wird in
im Beispiel unten.
Jetpack Compose kann den Fokus auf das nächste Element legen, das dem Anfang wie unten gezeigt, anstatt den Pfad zu wählen, den Sie für Navigation in eine Richtung:
<ph type="x-smartling-placeholder">In diesem Beispiel ist klar, dass die Entwickelnden nicht die Absicht hatten, sich auf wechseln Sie vom Tab Schokolade zum ersten Bild unten und zurück zum Tab Pastries (Süßgebäck). Stattdessen sollte der Fokus so lange auf den Tabs bleiben, bis die den letzten Tab und konzentrieren Sie sich dann auf den inneren Inhalt:
<ph type="x-smartling-placeholder">In Situationen, in denen es wichtig ist, dass eine Gruppe von zusammensetzbaren Funktionen
sequenziell, wie in der Tab-Zeile aus dem vorherigen Beispiel,
das Composable
in einem übergeordneten Element mit dem focusGroup()
-Modifikator:
LazyVerticalGrid(columns = GridCells.Fixed(4)) { item(span = { GridItemSpan(maxLineSpan) }) { Row(modifier = Modifier.focusGroup()) { FilterChipA() FilterChipB() FilterChipC() } } items(chocolates) { SweetsCard(sweets = it) } }
Die bidirektionale Navigation sucht nach der am besten zusammensetzbaren Funktion für die gegebene
Richtung: wenn ein Element aus einer anderen Gruppe näher an einem nicht vollständig sichtbaren
in der aktuellen Gruppe ausgewählt haben, wird das nächstgelegene ausgewählt. Um dies zu vermeiden
können Sie den focusGroup()
-Modifikator anwenden.
Mit FocusGroup
erscheint eine ganze Gruppe in Bezug auf den Fokus wie eine einzelne Entität.
aber die Gruppe selbst hat nicht den Fokus, sondern das nächstgelegene untergeordnete
konzentrieren Sie sich stattdessen. So kann die Navigation zu den nicht vollständig sichtbaren
Element vor dem Verlassen der Gruppe.
In diesem Fall werden die drei Instanzen von FilterChip
bevorzugt vor dem
SweetsCard
Elemente, auch wenn die SweetsCards
für das
Nutzer und einige FilterChip
sind möglicherweise ausgeblendet. Das liegt daran, dass der
Der focusGroup
-Modifikator weist den Fokusmanager an, die Reihenfolge anzupassen, in der die Elemente
fokussiert sind, damit die Navigation einfacher und kohärenter mit der Benutzeroberfläche ist.
Wenn FilterChipC
ohne den Modifikator focusGroup
nicht sichtbar war, fokussieren Sie
würde sie als Letztes aufnehmen. Durch das Hinzufügen eines solchen Modifizierers
nur sichtbar, aber auch direkt nach FilterChipB
in den Fokus rücken,
was die Nutzer erwarten.
Zusammensetzbare fokussierbare Funktion erstellen
Einige zusammensetzbare Funktionen sind standardmäßig fokussierbar, z. B. eine Schaltfläche oder eine zusammensetzbare Funktion mit
den daran angehängten clickable
-Modifikator. Wenn Sie eine spezifische
für eine zusammensetzbare Funktion verwenden, verwenden Sie den focusable
-Modifikator:
var color by remember { mutableStateOf(Green) } Box( Modifier .background(color) .onFocusChanged { color = if (it.isFocused) Blue else Green } .focusable() ) { Text("Focusable 1") }
Eine zusammensetzbare Funktion unfokussierbar machen
Es kann Situationen geben, in denen einige Ihrer Elemente nicht berücksichtigt werden sollten.
im Fokus. In diesen seltenen Fällen können Sie die canFocus property
um ein Composable
von der Fokussierung auszuschließen.
var checked by remember { mutableStateOf(false) } Switch( checked = checked, onCheckedChange = { checked = it }, // Prevent component from being focused modifier = Modifier .focusProperties { canFocus = false } )
Tastaturfokus mit FocusRequester
anfordern
In einigen Fällen können Sie den Fokus explizit als Antwort auf eine der Nutzerinteraktion. Sie können z. B. einen Nutzer fragen, ob er ein Formular ausfüllt und auf „Ja“ sollten Sie das erste Feld dieses Formats.
Verknüpfen Sie zuerst ein FocusRequester
-Objekt mit dem
zusammensetzbare Funktion, auf die Sie den Tastaturfokus verschieben möchten. Im folgenden Code
Snippet ist, wird ein FocusRequester
-Objekt mit einem TextField
verknüpft, indem ein
mit dem Namen Modifier.focusRequester
:
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) )
Sie können die Methode requestFocus
von FocusRequester aufrufen, um tatsächliche Fokusanfragen zu senden. Sie sollten diese Methode außerhalb eines Composable
-Kontexts aufrufen
(andernfalls wird es bei jeder Neuzusammensetzung neu ausgeführt). Das folgende Snippet
zeigt, wie das System aufgefordert wird, den Tastaturfokus zu verschieben, wenn die Schaltfläche
angeklickt:
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) ) Button(onClick = { focusRequester.requestFocus() }) { Text("Request focus on TextField") }
Fokus aufnehmen und loslassen
Sie können den Fokus nutzen, um Ihre Nutzer dazu anzuleiten, Ihrer App die richtigen Daten zur Verfügung zu stellen. bestimmte Aufgaben ausführen muss, z. B. eine gültige E-Mail-Adresse oder Telefonnummer anfordern. Nummer. Auch wenn Fehlerstatus Ihre Nutzenden darüber informieren, was passiert, benötigt das Feld mit fehlerhaften Informationen, um konzentriert zu bleiben, behoben.
Um den Fokus zu erfassen, können Sie die Methode captureFocus()
aufrufen.
Lassen Sie es anschließend mit der Methode freeFocus()
los, wie im folgenden Beispiel gezeigt:
Beispiel:
val textField = FocusRequester() TextField( value = text, onValueChange = { text = it if (it.length > 3) { textField.captureFocus() } else { textField.freeFocus() } }, modifier = Modifier.focusRequester(textField) )
Vorrang von Fokusmodifikatoren
Modifiers
sind Elemente, die nur ein untergeordnetes Element haben. Wenn Sie die Warteschlange
umschließt jedes Modifier
-Element links (oder oben) das Modifier
-Element, das auf
nach rechts (oder darunter). Das bedeutet, dass das zweite Modifier
-Element in einem
die erste, sodass bei der Deklaration von zwei focusProperties
nur die oberste
funktioniert, da sich die folgenden im obersten befinden.
Zur Verdeutlichung des Konzepts sehen Sie den folgenden Code:
Modifier .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
In diesem Fall zeigt die focusProperties
, die item2
als rechten Fokus angibt,
nicht verwendet werden, da im vorigen Abschnitt beschrieben. Somit ist item1
der Wert
einer verwendet.
Mit diesem Ansatz können Eltern das Verhalten
auch auf die Standardeinstellungen zurücksetzen,
mit FocusRequester.Default
:
Modifier .focusProperties { right = Default } .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
Das übergeordnete Element muss nicht Teil derselben Modifikatorkette sein. Ein Elternteil
zusammensetzbare Funktion kann die Fokuseigenschaft einer untergeordneten zusammensetzbaren Funktion überschreiben. Beispiel:
Sehen Sie sich folgendes FancyButton
an, das die Schaltfläche nicht fokussierbar macht:
@Composable fun FancyButton(modifier: Modifier = Modifier) { Row(modifier.focusProperties { canFocus = false }) { Text("Click me") Button(onClick = { }) { Text("OK") } } }
Ein Nutzer kann diese Schaltfläche wieder fokussierbar machen, indem er canFocus
auf true
setzt:
FancyButton(Modifier.focusProperties { canFocus = true })
Wie jedes Modifier
verhalten sich auch fokussierte Daten je nach Reihenfolge unterschiedlich.
die Sie deklariert haben. Mit folgendem Code wird beispielsweise die Box
fokussierbar, aber FocusRequester
ist diesem fokussierbaren Element nicht zugeordnet,
nach dem fokussierbaren Element deklariert.
Box( Modifier .focusable() .focusRequester(Default) .onFocusChanged {} )
Ein focusRequester
ist mit der ersten
in der Hierarchie darunter fokussierbar, sodass focusRequester
auf das
ersten fokussierbaren Kind. Falls keiner verfügbar ist, verweist er auf nichts.
Da Box
jedoch (dank des focusable()
-Modifikator) fokussierbar ist,
können Sie sie in zwei Richtungen aufrufen.
Als weiteres Beispiel würde eine der folgenden Aktionen funktionieren, da onFocusChanged()
ist das erste fokussierbare Element, das nach dem
focusable()
- oder focusTarget()
-Modifikatoren.
Box( Modifier .onFocusChanged {} .focusRequester(Default) .focusable() ) |
Box( Modifier .focusRequester(Default) .onFocusChanged {} .focusable() ) |
Fokus beim Betreten oder Verlassen der Seite umleiten
Manchmal müssen Sie eine sehr spezifische Art der Navigation bereitstellen, wie z. B. die wie in der Animation unten dargestellt:
<ph type="x-smartling-placeholder">Bevor wir näher darauf eingehen, sollten wir die Standardeinstellungen
der Fokussuche. Sobald der Fokus auf die Suche
erreicht das Element Clickable 3
, indem ich DOWN
auf dem Steuerkreuz (oder ein gleichwertiges Steuerelement) drückt
wird der Fokus auf den Bereich
unter Column
verschoben,
die Gruppe verlassen und die rechte
Gruppe ignorieren. Wenn keine
fokussierbaren Elementen verfügbar ist, wird der Fokus nicht verschoben, sondern auf
Clickable 3
Um dieses Verhalten zu ändern und die gewünschte Navigation zu ermöglichen, können Sie das
focusProperties
-Modifikator, mit dem Sie festlegen können, was passiert, wenn der Fokus
die Suche in den Composable
ein- oder beendet:
val otherComposable = remember { FocusRequester() } Modifier.focusProperties { exit = { focusDirection -> when (focusDirection) { Right -> Cancel Down -> otherComposable else -> Default } } }
Es ist möglich, den Fokus auf eine bestimmte Composable
zu richten, sobald diese in den
oder verlässt einen bestimmten Teil der Hierarchie, z. B. wenn Ihre Benutzeroberfläche zwei Elemente
und Sie möchten sicherstellen,
dass bei der ersten Verarbeitung
Fokus wechselt zur Sekunde:
Wenn in diesem GIF der Fokus Clickable 3 Composable
in Column
1 erreicht,
Das nächste fokussierte Element ist Clickable 4
in einem anderen Column
. Dieses Verhalten
kann erreicht werden, indem focusDirection
mit enter
und exit
kombiniert wird.
-Werte innerhalb des focusProperties
-Modifikator enthalten. Beide brauchen ein Lambda,
als Parameter die Richtung, aus der der Fokus kommt, und gibt ein
FocusRequester
Dieses Lambda kann sich auf drei verschiedene Arten verhalten:
FocusRequester.Cancel
verhindert, dass der Fokus fortgesetzt wird, während
FocusRequester.Default
ändert sein Verhalten nicht. Wenn Sie stattdessen die
Wenn FocusRequester
an ein weiteres Composable
-Element angehängt ist, springt der Fokus darauf
bestimmte Composable
.
Fortsetzungsrichtung des Fokus ändern
Um den Fokus auf das nächste Element oder eine bestimmte Richtung zu verschieben, können Sie
den onPreviewKey
-Modifikator zu nutzen und implizieren, dass LocalFocusManager
stellen Sie den Fokus mit dem moveFocus
-Modifikator vor.
Das folgende Beispiel zeigt das Standardverhalten des Fokusmechanismus: Wenn ein
tab
-Tastendruck erkannt, der Fokus rückt zum nächsten Element im Fokus
Liste. Normalerweise müssen Sie dies nicht konfigurieren,
um die Funktionsweise des Systems zu kennen, um die
verhalten.
val focusManager = LocalFocusManager.current var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.onPreviewKeyEvent { when { KeyEventType.KeyUp == it.type && Key.Tab == it.key -> { focusManager.moveFocus(FocusDirection.Next) true } else -> false } } )
In diesem Beispiel verlagert die Funktion focusManager.moveFocus()
den Fokus auf
zum angegebenen Element oder in die im Funktionsparameter angegebene Richtung.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Reagiere auf Konzentration
- Fokus auf „Schreiben“
- Reihenfolge des Fokusdurchlaufs ändern