Śledzenie widoczności w Compose

Śledzenie, kiedy element interfejsu jest widoczny na ekranie, jest przydatne w różnych przypadkach, np. podczas rejestrowania statystyk, 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 o zmianie widoczności funkcji kompozycyjnej. 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 dostarcza informacji o granicach elementu kompozycyjnego względem elementu głównego, okna i ekranu. Zapewnia kontrolę na niskim poziomie i jest podstawowym interfejsem API dla onVisibilityChanged. Modyfikator jest podobny do onGloballyPositioned, ale zapewnia lepszą wydajność i większą elastyczność.

Możesz używać tych interfejsów API z dowolnym elementem kompozycyjnym w ramach łańcucha modyfikatorów.

Śledzenie zmian widoczności za pomocą onVisibilityChanged

Wiedza o tym, kiedy element jest widoczny lub częściowo widoczny dla użytkownika, może pomóc w śledzeniu statystyk (np. liczby wyświetleń), optymalizowaniu wydajności (pobieraniu lub wstępnym pobieraniu danych z sieci tylko wtedy, gdy element jest widoczny), a nawet wywoływaniu zdarzeń (odtwarzaniu lub wstrzymywaniu filmów).

Aby otrzymywać powiadomienia o zmianie widoczności elementu, użyj modyfikatora onVisibilityChanged, jak 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 udostępnia wartość logiczną, która odzwierciedla bieżący stan widoczności elementu kompozycyjnego. Dodatkowo oferuje parametry takie jak minFraction i minDurationMs, 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ę typu „composable”, która renderuje tekst z dopełnieniem. Aby modyfikator wpływał na cały element kompozycyjny wraz z dopełnieniem, dodaj modyfikator onVisibilityChanged przed modyfikatorem padding.

Ustawianie limitu czasu dla funkcji kompozycyjnej 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 on widoczny dla użytkownika przez określony 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 który element kompozycyjny musi być stale widoczny, aby wywołanie zwrotne zostało aktywowane. Jeśli element kompozycyjny przestanie być widoczny przed upływem tego czasu, licznik czasu zostanie zresetowany. Wartość domyślna to 0 milisekund.

Poniższy fragment kodu zmienia tło na fioletowe, gdy element kompozycyjny jest widoczny 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 się z różowego na śliwkowe, gdy element kompozycyjny jest wyświetlany na ekranie nieprzerwanie przez 3 sekundy.

Ustawianie minimalnego widocznego ułamka

Ustawienie minimalnej widocznej części dla wywołania zwrotnego widoczności funkcji kompozycyjnej 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ć, jaka część elementu kompozycyjnego musi być widoczna na ekranie, aby został on oznaczony jako widoczny. Obsługuje wartości zmiennoprzecinkowe z zakresu od 0.0f do 1.0f, a domyślnie jest ustawiony na 1.0f. 1.0f oznacza, że element kompozycyjny musi być całkowicie widoczny na ekranie, aby wywołanie zwrotne zostało aktywowane.

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 ustawiania minFractionVisible. Rysunek 3. minFractionVisible ustawiono na 0.2f.

W przykładzie użytym wcześniej boty Androidify są wstępnie wczytywane z sieci, zanim funkcja kompozycyjna stanie się całkowicie widoczna. Na rysunku 2 trzeci bot się nie wczytuje, ponieważ element kompozycyjny nie jest w pełni widoczny. Na rysunku 3 ustawiono wartość minFractionVisible, a trzeci bot wczytuje się, zanim stanie się całkowicie widoczny na ekranie.