Zum Aktualisieren nach unten ziehen

Mit der Komponente „Zum Aktualisieren nach unten ziehen“ können Nutzer am Anfang des Inhalts einer App nach unten ziehen, um die Daten zu aktualisieren.

API-Oberfläche

Verwenden Sie die komponierbare Funktion PullToRefreshBox, um die Funktion „Zum Aktualisieren nach unten ziehen“ zu implementieren. Sie fungiert als Container für Ihre scrollbaren Inhalte. Die folgenden Schlüsselparameter steuern das Aktualisierungsverhalten und das Erscheinungsbild:

  • isRefreshing: Ein boolescher Wert, der angibt, ob die Aktualisierungsaktion gerade ausgeführt wird.
  • onRefresh: Eine Lambda-Funktion, die ausgeführt wird, wenn der Nutzer eine Aktualisierung initiiert.
  • indicator: Passt die Anzeige an, die das System beim Aktualisieren durch Herunterziehen darstellt.

Einfaches Beispiel

Dieses Snippet zeigt die grundlegende Verwendung von PullToRefreshBox:

@Composable
fun PullToRefreshBasicSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

Wichtige Punkte zum Code

  • PullToRefreshBox umschließt ein LazyColumn, das eine Liste von Strings anzeigt.
  • Für PullToRefreshBox sind die Parameter isRefreshing und onRefresh erforderlich.
  • Der Inhalt im PullToRefreshBox-Block stellt den scrollbaren Inhalt dar.

Ergebnis

In diesem Video wird die grundlegende Implementierung von „Zum Aktualisieren nach unten ziehen“ aus dem vorherigen Code gezeigt:

Abbildung 1: Eine einfache Implementierung von „Zum Aktualisieren nach unten ziehen“ für eine Liste von Elementen.

Erweitertes Beispiel: Farbe des Indikators anpassen

@Composable
fun PullToRefreshCustomStyleSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            Indicator(
                modifier = Modifier.align(Alignment.TopCenter),
                isRefreshing = isRefreshing,
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                color = MaterialTheme.colorScheme.onPrimaryContainer,
                state = state
            )
        },
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

Wichtige Punkte zum Code

  • Die Farbe des Indikators wird über die Attribute containerColor und color im Parameter indicator angepasst.
  • rememberPullToRefreshState() verwaltet den Status der Aktualisierungsaktion. Sie verwenden diesen Status in Verbindung mit dem Parameter indicator.

Ergebnis

Dieses Video zeigt eine Implementierung der Funktion „Zum Aktualisieren nach unten ziehen“ mit einer farbigen Anzeige:

Abbildung 2: Eine Implementierung von „Zum Aktualisieren nach unten ziehen“ mit einem benutzerdefinierten Stil.

Beispiel für Fortgeschrittene: Vollständig angepassten Indikator erstellen

Sie können komplexe benutzerdefinierte Indikatoren erstellen, indem Sie vorhandene Composables und Animationen nutzen.In diesem Snippet wird gezeigt, wie Sie einen vollständig benutzerdefinierten Indikator in Ihrer Implementierung von „Zum Aktualisieren nach unten ziehen“ erstellen:

@Composable
fun PullToRefreshCustomIndicatorSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            MyCustomIndicator(
                state = state,
                isRefreshing = isRefreshing,
                modifier = Modifier.align(Alignment.TopCenter)
            )
        }
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

// ...
@Composable
fun MyCustomIndicator(
    state: PullToRefreshState,
    isRefreshing: Boolean,
    modifier: Modifier = Modifier,
) {
    Box(
        modifier = modifier.pullToRefresh(
            state = state,
            isRefreshing = isRefreshing,
            threshold = PositionalThreshold,
            onRefresh = {

            }
        ),
        contentAlignment = Alignment.Center
    ) {
        Crossfade(
            targetState = isRefreshing,
            animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS),
            modifier = Modifier.align(Alignment.Center)
        ) { refreshing ->
            if (refreshing) {
                CircularProgressIndicator(Modifier.size(SPINNER_SIZE))
            } else {
                val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) }
                Icon(
                    imageVector = Icons.Filled.CloudDownload,
                    contentDescription = "Refresh",
                    modifier = Modifier
                        .size(18.dp)
                        .graphicsLayer {
                            val progress = distanceFraction()
                            this.alpha = progress
                            this.scaleX = progress
                            this.scaleY = progress
                        }
                )
            }
        }
    }
}

Wichtige Punkte zum Code

  • Im vorherigen Snippet wurde die von der Bibliothek bereitgestellte Indicator verwendet. In diesem Snippet wird eine benutzerdefinierte Indikator-Composable namens MyCustomIndicator erstellt. In dieser zusammensetzbaren Funktion übernimmt der pullToRefreshIndicator-Modifikator die Positionierung und das Auslösen einer Aktualisierung.
  • Wie im vorherigen Snippet wird im Beispiel die PullToRefreshState-Instanz extrahiert, sodass Sie dieselbe Instanz sowohl an PullToRefreshBox als auch an pullToRefreshModifier übergeben können.
  • In diesem Beispiel werden die Containerfarbe und der Positionsschwellenwert aus der Klasse PullToRefreshDefaults verwendet. So können Sie das Standardverhalten und das Styling aus der Material-Bibliothek wiederverwenden und nur die Elemente anpassen, die Sie interessieren.
  • MyCustomIndicator verwendet Crossfade, um zwischen einem Cloud-Symbol und einem CircularProgressIndicator zu wechseln. Das Wolkensymbol wird größer, wenn der Nutzer zieht, und wechselt zu einem CircularProgressIndicator, wenn die Aktualisierungsaktion beginnt.
    • targetState verwendet isRefreshing, um zu bestimmen, welcher Status angezeigt werden soll (das Cloud-Symbol oder die kreisförmige Fortschrittsanzeige).
    • animationSpec definiert eine tween-Animation für den Übergang mit einer angegebenen Dauer von CROSSFADE_DURATION_MILLIS.
    • state.distanceFraction gibt an, wie weit der Nutzer nach unten gezogen hat, von 0f (nicht gezogen) bis 1f (vollständig gezogen).
    • Der Modifikator graphicsLayer ändert die Skalierung und Transparenz.

Ergebnis

In diesem Video wird der benutzerdefinierte Indikator aus dem vorherigen Code gezeigt:

Abbildung 3: Eine Implementierung von „Zum Aktualisieren nach unten ziehen“ mit einer benutzerdefinierten Anzeige.

Zusätzliche Ressourcen