Rastreamento de visibilidade no Compose

Rastrear quando um elemento da interface está visível na tela é útil para vários casos de uso, como registrar análises, gerenciar o estado da interface e otimizar recursos reproduzindo ou pausando automaticamente o conteúdo de vídeo. O Compose oferece vários modificadores para rastrear a visibilidade de elementos da interface, como:

  • onVisibilityChanged: esse modificador notifica quando a visibilidade de um elemento combinável muda. É ideal para acionar uma ação ou efeito colateral sempre que o elemento combinável fica visível.
  • onLayoutRectChanged: esse modificador fornece informações sobre os limites de um elemento combinável em relação à raiz, à janela e à tela. Ela oferece controle de baixo nível e é a API de base para onVisibilityChanged. O modificador é semelhante a onGloballyPositioned, mas oferece melhor desempenho e maior flexibilidade.

Você pode usar essas APIs com qualquer elemento combinável como parte da cadeia de modificadores.

Acompanhe as mudanças de visibilidade com onVisibilityChanged

Entender quando um item está visível ou parcialmente visível para um usuário pode ajudar você a rastrear análises (por exemplo, contagem de espectadores), otimizar o desempenho (buscando ou pré-buscando dados da rede somente quando o item está visível) ou até mesmo acionar eventos (reproduzindo ou pausando vídeos).

Para receber uma notificação quando a visibilidade de um item mudar, use o modificador onVisibilityChanged, como mostrado no exemplo a seguir:

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

O modificador onVisibilityChanged fornece um valor booleano que reflete o estado de visibilidade atual do elemento combinável. Além disso, ele oferece parâmetros como minFraction e minDurationMs, que oferecem um controle mais preciso sobre quando o callback de visibilidade precisa ser acionado.

Assim como acontece com todos os outros modificadores, a sequência é importante com o modificador onVisibilityChanged. O exemplo anterior mostra uma função combinável que renderiza texto com padding. Para garantir que o modificador afete todo o elemento combinável junto com o padding, adicione o modificador onVisibilityChanged antes do modificador padding.

Definir um limite de tempo em um elemento combinável antes de acionar o callback de visibilidade

Em algumas situações, talvez você queira acionar uma ação somente depois que um item ficar visível para o usuário por um determinado período. Por exemplo, você pode reproduzir automaticamente um vídeo se ele estiver visível para o usuário há algum tempo.

Para acionar uma ação depois que um item fica visível por um período definido, use o parâmetro minDurationMs no modificador onVisibilityChanged. Esse parâmetro especifica o tempo mínimo que um elemento combinável precisa ficar continuamente visível para que o callback seja acionado. Se o elemento combinável deixar de ficar visível antes que a duração seja atingida, o timer será redefinido. O valor padrão é 0 milissegundos.

O snippet a seguir muda o plano de fundo para roxo depois que o elemento combinável fica visível para o usuário por três segundos:

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

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

Figura 1. O plano de fundo muda de rosa para ameixa depois que o elemento combinável fica na tela por 3 segundos seguidos.

Definir uma fração mínima visível

Definir uma fração mínima visível para o callback de visibilidade do elemento combinável é útil ao trabalhar com conteúdo rolável (por exemplo, LazyColumn) para otimizar a busca de dados para itens que excedem o tamanho da tela.

Nesses casos, use o parâmetro minFractionVisible no modificador onVisibilityChanged para definir a fração que precisa estar na tela para que o elemento combinável seja marcado como visível. Ele aceita valores de ponto flutuante que variam de 0.0f a 1.0f e é definido como 1.0f por padrão. 1.0f significa que o elemento combinável precisa estar completamente visível na tela para que o callback seja acionado.

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

Figura 2. Sem minFractionVisible definido. Figura 3. Com minFractionVisible definido como 0.2f.

O exemplo usado anteriormente pré-carrega os bots do Androidify da rede antes que o elemento combinável fique totalmente visível. Na Figura 2, o terceiro bot não é carregado porque o elemento combinável não está totalmente visível. Na Figura 3, minFractionVisible está definido, e o terceiro bot é carregado antes de ficar completamente visível na tela.