Śledzenie widoczności w Compose

Śledzenie widoczności elementu interfejsu na ekranie jest przydatne w różnych przypadkach, np. do rejestrowania danych analitycznych, zarządzania stanem interfejsu i optymalizowania zasobów przez automatyczne odtwarzanie lub wstrzymywanie treści wideo. Compose oferuje kilka modyfikatorów do śledzenia widoczności elementów interfejsu, takich jak:

  • onVisibilityChanged – ten modyfikator powiadamia Cię, gdy zmienia się widoczność komponentu. Jest to idealne rozwiązanie do wywoływania działania lub efektu ubocznego za każdym razem, gdy element kompozycyjny staje się widoczny.
  • onLayoutRectChanged – ten modyfikator zawiera informacje o granicach komponentu w stosunku do elementu głównego, okna i ekranu. Zapewnia on kontrolę na niskim poziomie i jest podstawowym interfejsem API dla onVisibilityChanged. Modyfikator jest podobny do onGloballyPositioned, ale zapewnia większą skuteczność i elastyczność.

Możesz używać tych interfejsów API z dowolnym komponentem, który można łączyć, w ramach łańcucha modyfikatorów.

Śledzenie zmian widoczności za pomocą onVisibilityChanged

Informacje o tym, kiedy element jest widoczny lub częściowo widoczny dla użytkownika, mogą pomóc w śledzeniu danych analitycznych (np. liczby wyświetleń), optymalizacji wydajności (pobieranie lub wstępne pobieranie danych z sieci tylko wtedy, gdy element jest widoczny) lub nawet wywoływaniu zdarzeń (odtwarzanie lub wstrzymywanie filmów).

Aby otrzymywać powiadomienia o zmianach widoczności elementu, użyj modyfikatora onVisibilityChanged, jak pokazano w tym przykładzie:

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

Modyfikator onVisibilityChanged zwraca wartość logiczną odzwierciedlającą bieżący stan widoczności komponentu kompozycyjnego. Dodatkowo udostępnia parametry takie jak minFractionminDurationMs, które zapewniają większą kontrolę nad tym, kiedy należy wywołać wywołanie zwrotne widoczności.

Podobnie jak w przypadku innych modyfikatorów kolejność ma znaczenie w przypadku modyfikatora onVisibilityChanged. Powyższy przykład pokazuje funkcję kompozycyjną, która renderuje tekst z dopełnieniem. Aby mieć pewność, że modyfikator wpływa na cały element kompozycyjny wraz z dopełnieniem, dodaj modyfikator onVisibilityChanged przed modyfikatorem padding.

Ustawianie limitu czasu dla elementu kompozycyjnego przed wywołaniem wywołania zwrotnego widoczności

W niektórych sytuacjach możesz chcieć wywołać działanie dopiero po tym, jak element będzie widoczny dla użytkownika przez określony czas. Możesz na przykład automatycznie odtwarzać film, jeśli jest widoczny dla użytkownika przez pewien czas.

Aby wywołać działanie po tym, jak element będzie widoczny przez określony czas, użyj parametru minDurationMs w modyfikatorze onVisibilityChanged. Ten parametr określa minimalny czas, przez jaki element kompozycyjny musi być stale widoczny, aby wywołać wywołanie zwrotne. Jeśli element kompozycyjny przestanie być widoczny przed upływem określonego czasu, licznik zostanie zresetowany. Wartością domyślną jest 0 milisekund.

Poniższy fragment kodu zmienia kolor tła na fioletowy po tym, jak funkcja kompozycyjna jest widoczna dla użytkownika przez 3 sekundy:

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

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

Rysunek 1. Tło zmienia kolor z różowego na śliwkowy po 3 sekundach ciągłego wyświetlania komponentu.

Ustawianie minimalnego widocznego ułamka

Ustawienie minimalnego widocznego ułamka w przypadku wywołania zwrotnego widoczności komponentu jest przydatne podczas pracy z treściami, które można przewijać (np. LazyColumn), aby zoptymalizować pobieranie danych w przypadku elementów, które przekraczają rozmiar ekranu.

W takich przypadkach użyj parametru minFractionVisible w modyfikatorze onVisibilityChanged, aby określić ułamek, który musi być widoczny na ekranie, aby element kompozycyjny został oznaczony jako widoczny. Obsługuje wartości zmiennoprzecinkowe z zakresu od 0.0f do 1.0f, a domyślnie jest ustawiona na 1.0f. 1.0f oznacza, że element kompozycyjny musi być w całości widoczny na ekranie, aby wywołać wywołanie zwrotne.

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)
            )
        }
    }
}

Rysunek 2. Bez ustawienia minFractionVisible. Rysunek 3. Wartość minFractionVisible to 0.2f.

W przykładzie użyto wcześniejszego wstępnego wczytywania botów Androidify z sieci, zanim komponent będzie w pełni widoczny. Na rysunku 2 trzeci bot nie wczytuje się, ponieważ element kompozycyjny nie jest w pełni widoczny. Na ilustracji 3 parametr minFractionVisible jest ustawiony, a trzeci bot wczytuje się, zanim będzie w pełni widoczny na ekranie.