Symbolschaltflächen

Symbolschaltflächen zeigen Aktionen an, die Nutzer ausführen können. Symbolschaltflächen müssen ein Symbol mit einer klaren Bedeutung verwenden und stellen in der Regel gängige oder häufig verwendete Aktionen dar.

Es gibt zwei Arten von Symbolschaltflächen:

  • Standard: Über diese Schaltflächen können andere Elemente geöffnet werden, z. B. ein Menü oder die Suche.
  • Umschaltfläche: Diese Buttons können binäre Aktionen darstellen, die aktiviert oder deaktiviert werden können, z. B. „Favorit“ oder „Lesezeichen“.
5 Symbolschaltflächen mit verschiedenen Symbolen (Einstellungen, Mehr usw.). Einige sind ausgefüllt, was auf eine Auswahl hinweist, und andere sind umrandet.
Abbildung 1. Symbolschaltflächen, von denen einige gefüllt (was auf eine Auswahl hinweist) und umrandet sind.

API-Oberfläche

Verwenden Sie das Compose-Element IconButton, um Standard-Symbolschaltflächen zu implementieren. Wenn Sie verschiedene visuelle Stile wie „Ausgefüllt“, „Ausgefüllt, tonal“ oder „Umrandet“ erstellen möchten, verwenden Sie FilledIconButton, FilledTonalIconButton bzw. OutlinedIconButton.

Zu den wichtigsten Parametern für IconButton gehören:

  • onClick: Eine Lambda-Funktion, die ausgeführt wird, wenn der Nutzer auf die Symbolschaltfläche tippt.
  • enabled: Ein boolescher Wert, der den Aktivierungsstatus der Schaltfläche steuert. Wenn false, reagiert die Schaltfläche nicht auf Nutzereingaben.
  • content: Der zusammensetzbare Inhalt innerhalb der Schaltfläche, normalerweise ein Icon.

Einfaches Beispiel: Symbolschaltfläche zum Ein-/Ausschalten

In diesem Beispiel wird gezeigt, wie Sie eine Umschaltschaltfläche mit Symbol implementieren. Das Aussehen einer Umschalt-Symbolschaltfläche ändert sich je nachdem, ob sie ausgewählt ist oder nicht.

@Preview
@Composable
fun ToggleIconButtonExample() {
    // isToggled initial value should be read from a view model or persistent storage.
    var isToggled by rememberSaveable { mutableStateOf(false) }

    IconButton(
        onClick = { isToggled = !isToggled }
    ) {
        Icon(
            painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite),
            contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button."
        )
    }
}

Wichtige Punkte zum Code

  • Das ToggleIconButtonExample-Composable definiert ein umschaltbares IconButton.
    • mutableStateOf(false) erstellt ein MutableState-Objekt, das einen booleschen Wert enthält, der anfänglich false ist. Dadurch wird isToggled zu einem State Holder, d. h., Compose setzt die UI neu zusammen, wenn sich der Wert ändert.
    • rememberSaveable sorgt dafür, dass der Status von isToggled bei Konfigurationsänderungen wie der Bildschirmdrehung erhalten bleibt.
  • Der Lambda-Ausdruck onClick von IconButton definiert das Verhalten des Buttons beim Klicken und wechselt den Status zwischen true und false.
  • Der Parameter painter des Compose-Elements Icon lädt je nach isToggled-Status eine andere painterResource. Dadurch ändert sich das Erscheinungsbild des Symbols.
    • Wenn isToggled den Wert true hat, wird das ausgefüllte Herz-Drawable geladen.
    • Wenn isToggled den Wert false hat, wird das Drawable mit dem umrandeten Herz geladen.
  • Der contentDescription des Icon wird ebenfalls basierend auf dem isToggled-Status aktualisiert, um entsprechende Informationen zur Barrierefreiheit bereitzustellen.

Ergebnis

Die folgende Abbildung zeigt die Umschalttaste aus dem vorherigen Snippet im nicht ausgewählten Zustand:

Ein Favoriten-Umschaltsymbol (ein Herz) im nicht ausgewählten Zustand (nicht ausgefüllt).
Abbildung 2: Ein „Favorit“-Umschaltsymbol im nicht ausgewählten Zustand.

Erweitertes Beispiel: Wiederholte Aktionen beim Drücken

In diesem Abschnitt wird gezeigt, wie Sie Symbolschaltflächen erstellen, die eine Aktion kontinuierlich auslösen, während der Nutzer sie gedrückt hält, anstatt sie nur einmal pro Klick auszulösen.

@Composable
fun MomentaryIconButton(
    unselectedImage: Int,
    selectedImage: Int,
    contentDescription: String,
    modifier: Modifier = Modifier,
    stepDelay: Long = 100L, // Minimum value is 1L milliseconds.
    onClick: () -> Unit
) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val pressedListener by rememberUpdatedState(onClick)

    LaunchedEffect(isPressed) {
        while (isPressed) {
            delay(stepDelay.coerceIn(1L, Long.MAX_VALUE))
            pressedListener()
        }
    }

    IconButton(
        modifier = modifier,
        onClick = onClick,
        interactionSource = interactionSource
    ) {
        Icon(
            painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage),
            contentDescription = contentDescription,
        )
    }
}

Wichtige Punkte zum Code

  • MomentaryIconButton verwendet unselectedImage: Int, die ID der zeichenfähigen Ressource für das Symbol, wenn die Taste nicht gedrückt ist, und selectedImage: Int, die ID der zeichenfähigen Ressource für das Symbol, wenn die Taste gedrückt ist.
  • Es wird ein interactionSource verwendet, um speziell „Drücken“-Interaktionen des Nutzers zu erfassen.
  • isPressed ist „true“, wenn die Taste gerade gedrückt wird, andernfalls „false“. Wenn isPressed den Wert true hat, wird die LaunchedEffect in einer Schleife ausgeführt.
    • In dieser Schleife wird ein delay (mit stepDelay) verwendet, um Pausen zwischen den auslösenden Aktionen zu erstellen. coerceIn sorgt dafür, dass die Verzögerung mindestens 1 ms beträgt, um Endlosschleifen zu verhindern.
    • pressedListener wird nach jeder Verzögerung innerhalb der Schleife aufgerufen. Dadurch wird die Aktion wiederholt.
  • pressedListener verwendet rememberUpdatedState, um sicherzustellen, dass der onClick-Lambda-Ausdruck (die auszuführende Aktion) immer die aktuellste Version aus der neuesten Komposition ist.
  • Das angezeigte Bild des Icon ändert sich je nachdem, ob die Taste gerade gedrückt wird oder nicht.
    • Wenn isPressed „true“ ist, wird selectedImage angezeigt.
    • Andernfalls wird unselectedImage angezeigt.

Verwenden Sie als Nächstes diese MomentaryIconButton in einem Beispiel. Das folgende Snippet zeigt zwei Symbolschaltflächen, die einen Zähler steuern:

@Preview()
@Composable
fun MomentaryIconButtonExample() {
    var pressedCount by remember { mutableIntStateOf(0) }

    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_rewind,
            selectedImage = R.drawable.fast_rewind_filled,
            stepDelay = 100L,
            onClick = { pressedCount -= 1 },
            contentDescription = "Decrease count button"
        )
        Spacer(modifier = Modifier)
        Text("advanced by $pressedCount frames")
        Spacer(modifier = Modifier)
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_forward,
            selectedImage = R.drawable.fast_forward_filled,
            contentDescription = "Increase count button",
            stepDelay = 100L,
            onClick = { pressedCount += 1 }
        )
    }
}

Wichtige Punkte zum Code

  • Die komponierbare Funktion MomentaryIconButtonExample zeigt einen Row mit zwei MomentaryIconButton-Instanzen und einer komponierbaren Funktion Text an, um eine UI zum Erhöhen und Verringern eines Zählers zu erstellen.
  • Es wird eine änderbare Zustandsvariable pressedCount mit remember und mutableIntStateOf verwaltet, die mit 0 initialisiert wird. Wenn sich pressedCount ändert, werden alle beobachtenden Composables (z. B. das Composable Text) neu zusammengesetzt, um den neuen Wert widerzuspiegeln.
  • Mit dem ersten MomentaryIconButton wird pressedCount verringert, wenn du darauf klickst oder die Taste gedrückt hältst.
  • Der zweite MomentaryIconButton erhöht pressedCount, wenn er angeklickt oder gedrückt gehalten wird.
  • Beide Schaltflächen verwenden einen stepDelay von 100 Millisekunden. Das bedeutet, dass die Aktion onClick alle 100 ms wiederholt wird, während eine Schaltfläche gedrückt gehalten wird.

Ergebnis

Das folgende Video zeigt die Benutzeroberfläche mit den Symbolschaltflächen und dem Zähler:

Abbildung 3: Eine Zähler-UI mit zwei Symbolschaltflächen (Plus und Minus), mit denen der Zähler erhöht und verringert wird.

Zusätzliche Ressourcen