Sichtbarkeits-Tracking in Compose

Das Erfassen, wann ein UI-Element auf dem Bildschirm sichtbar ist, ist für eine Vielzahl von Anwendungsfällen hilfreich, z. B. für das Logging von Analysen, das Verwalten des UI-Status und das Optimieren von Ressourcen durch automatisches Abspielen oder Pausieren von Videoinhalten. Compose bietet mehrere Modifikatoren zum Erfassen der Sichtbarkeit von UI-Elementen, z. B.:

  • onVisibilityChanged: Dieser Modifikator benachrichtigt Sie, wenn sich die Sichtbarkeit einer zusammensetzbaren Funktion ändert. Sie eignet sich ideal, um jedes Mal, wenn die Komposition sichtbar wird, eine Aktion oder einen Nebeneffekt auszulösen.
  • onLayoutRectChanged: Dieser Modifikator liefert Informationen zu den Grenzen einer zusammensetzbaren Funktion im Verhältnis zum Stamm, Fenster und Bildschirm. Sie bietet Low-Level-Steuerung und ist die Foundation API für onVisibilityChanged. Der Modifikator ähnelt onGloballyPositioned, bietet aber eine bessere Leistung und mehr Flexibilität.

Sie können diese APIs mit jeder beliebigen komponierbaren Funktion als Teil der Modifikatorkette verwenden.

Sichtbarkeitsänderungen mit onVisibilityChanged verfolgen

Wenn Sie wissen, wann ein Element für einen Nutzer sichtbar oder teilweise sichtbar ist, können Sie Analysen verfolgen (z. B. die Anzahl der Zuschauer), die Leistung optimieren (Daten nur dann aus dem Netzwerk abrufen oder vorab abrufen, wenn das Element sichtbar ist) oder sogar Ereignisse auslösen (Videos abspielen oder pausieren).

Wenn Sie benachrichtigt werden möchten, wenn sich die Sichtbarkeit eines Elements ändert, verwenden Sie den Modifikator onVisibilityChanged, wie im folgenden Beispiel gezeigt:

Text(
    text = "Some text",
    modifier = Modifier
        .onVisibilityChanged { visible ->
            if (visible) {
                // Do something if visible
            } else {
                // Do something if not visible
            }
        }
        .padding(vertical = 8.dp)
)

Der Modifikator onVisibilityChanged liefert einen booleschen Wert, der den aktuellen Sichtbarkeitsstatus der zusammensetzbaren Funktion widerspiegelt. Außerdem bietet sie Parameter wie minFraction und minDurationMs, mit denen Sie genauer steuern können, wann der Sichtbarkeits-Callback ausgelöst werden soll.

Wie bei jedem anderen Modifikator ist die Reihenfolge beim Modifikator onVisibilityChanged wichtig. Das vorherige Beispiel zeigt eine zusammensetzbare Funktion, die Text mit Padding rendert. Damit sich der Modifikator auf das gesamte Compose-Element und das Padding auswirkt, fügen Sie den Modifikator onVisibilityChanged vor dem Modifikator padding hinzu.

Zeitlimit für ein Compose-Element festlegen, bevor der Sichtbarkeits-Callback ausgelöst wird

In manchen Situationen möchten Sie eine Aktion möglicherweise erst dann auslösen, wenn ein Element für eine bestimmte Zeit für den Nutzer sichtbar war. Sie können beispielsweise ein Video automatisch abspielen, wenn es für den Nutzer eine Zeit lang sichtbar war.

Wenn Sie eine Aktion auslösen möchten, nachdem ein Element für einen bestimmten Zeitraum sichtbar war, verwenden Sie den Parameter minDurationMs im Modifikator onVisibilityChanged. Dieser Parameter gibt die Mindestdauer an, die eine komponierbare Funktion kontinuierlich sichtbar sein muss, damit der Callback ausgelöst wird. Wenn das Compose-Element nicht mehr sichtbar ist, bevor die Dauer erreicht ist, wird der Timer zurückgesetzt. Der Standardwert ist 0 Millisekunden.

Im folgenden Snippet wird der Hintergrund in Lila geändert, nachdem die komponierbare Funktion 3 Sekunden lang für den Nutzer sichtbar war:

var background by remember { mutableStateOf(PalePink) }
Card(
    modifier = modifier
        // ...
        .onVisibilityChanged(minDurationMs = 3000) {
            if (it) {
                background = MutedPlum
            }
        }
) {

    Box(
        modifier = Modifier
            // ...
            .background(background),
        contentAlignment = Alignment.Center,
    ) {
        // ...
    }
}

Abbildung 1. Der Hintergrund ändert sich von Rosa zu Pflaume, nachdem die komponierbare Funktion 3 Sekunden lang ununterbrochen auf dem Bildschirm zu sehen war.

Mindestanteil der Sichtbarkeit festlegen

Wenn Sie mit scrollbaren Inhalten arbeiten (z. B. LazyColumn), ist es sinnvoll, einen minimalen sichtbaren Bruchteil für den Sichtbarkeits-Callback des Composables festzulegen, um den Datenabruf für Elemente zu optimieren, die die Bildschirmgröße überschreiten.

Verwenden Sie in solchen Fällen den Parameter minFractionVisible im Modifikator onVisibilityChanged, um den Anteil zu definieren, der auf dem Bildschirm zu sehen sein muss, damit die komponierbare Funktion als sichtbar markiert wird. Es werden Gleitkommawerte von 0.0f bis 1.0f unterstützt. Der Standardwert ist 1.0f. 1.0f bedeutet, dass die komponierbare Funktion vollständig auf dem Bildschirm sichtbar sein muss, damit der Callback ausgelöst wird.

LazyColumn(
    modifier = modifier.fillMaxSize()
) {
    item {
        Box(
            modifier = Modifier
                // ...
                // Here the visible callback gets triggered when 20% of the composable is visible
                .onVisibilityChanged(
                    minFractionVisible = 0.2f,
                ) { visible ->
                    if (visible) {
                        // Call specific logic here
                        // viewModel.fetchDataFromNetwork()
                    }
                }
                .padding(vertical = 16.dp)
        ) {
            Text(
                text = "Sample Text",
                modifier = Modifier.padding(horizontal = 16.dp)
            )
        }
    }
}

Abbildung 2: Ohne dass minFractionVisible festgelegt ist. Abbildung 3: minFractionVisible ist auf 0.2f festgelegt.

Im vorherigen Beispiel werden die Androidify-Bots aus dem Netzwerk vorab geladen, bevor die zusammensetzbare Funktion vollständig sichtbar ist. In Abbildung 2 wird der dritte Bot nicht geladen, da das Composable nicht vollständig sichtbar ist. In Abbildung 3 ist minFractionVisible festgelegt und der dritte Bot wird geladen, bevor er auf dem Bildschirm vollständig sichtbar ist.