Seguimiento de visibilidad en Compose

Hacer un seguimiento de cuándo un elemento de la IU está visible en la pantalla es útil para una variedad de casos de uso, como el registro de estadísticas, la administración del estado de la IU y la optimización de recursos a través de la reproducción o la pausa automáticas del contenido de video. Compose ofrece varios modificadores para hacer un seguimiento de la visibilidad de los elementos de la IU, como los siguientes:

  • onVisibilityChanged: Este modificador te notifica cuando cambia la visibilidad de un elemento componible. Es ideal para activar una acción o un efecto secundario cada vez que el elemento componible se vuelve visible.
  • onLayoutRectChanged: Este modificador proporciona información sobre los límites de un elemento componible en relación con la raíz, la ventana y la pantalla. Ofrece control de bajo nivel y es la API fundamental para onVisibilityChanged. El modificador es similar a onGloballyPositioned, pero ofrece un mejor rendimiento y mayor flexibilidad.

Puedes usar estas APIs con cualquier elemento componible como parte de la cadena de modificadores.

Haz un seguimiento de los cambios de visibilidad con onVisibilityChanged

Comprender cuándo un elemento es visible o parcialmente visible para un usuario puede ayudarte a hacer un seguimiento de las estadísticas (por ejemplo, el recuento de usuarios), optimizar el rendimiento (recuperar o precargar datos de la red solo cuando el elemento es visible) o incluso activar eventos (reproducir o pausar videos).

Para recibir una notificación cuando cambia la visibilidad de un elemento, usa el modificador onVisibilityChanged, como se muestra en el siguiente ejemplo:

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

El modificador onVisibilityChanged proporciona un valor booleano que refleja el estado de visibilidad actual del elemento componible. Además, ofrece parámetros como minFraction y minDurationMs, que te brindan un mayor control sobre cuándo se debe activar la devolución de llamada de visibilidad.

Al igual que con cualquier otro modificador, la secuencia importa con el modificador onVisibilityChanged. En el ejemplo anterior, se muestra una función de componibilidad que renderiza texto con padding. Para asegurarte de que el modificador afecte a todo el elemento componible junto con el padding, agrega el modificador onVisibilityChanged antes del modificador padding.

Establece un límite de tiempo en un elemento componible antes de activar la devolución de llamada de visibilidad

En algunas situaciones, es posible que desees activar una acción solo después de que un elemento haya estado visible para el usuario durante un cierto período. Por ejemplo, puedes reproducir automáticamente un video si el usuario lo vio durante un tiempo.

Para activar una acción después de que un elemento sea visible durante un período definido, usa el parámetro minDurationMs en el modificador onVisibilityChanged. Este parámetro especifica la cantidad mínima de tiempo que un elemento componible debe estar visible de forma continua para que se active la devolución de llamada. Si el elemento componible deja de ser visible antes de que se cumpla la duración, se restablece el temporizador. El valor predeterminado es 0 milisegundos.

El siguiente fragmento cambia el fondo a morado después de que el elemento componible haya estado visible para el usuario durante 3 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. El fondo cambia de rosa a ciruela después de que el elemento componible aparece en la pantalla durante 3 segundos continuos.

Establece una fracción visible mínima

Establecer una fracción visible mínima para la devolución de llamada de visibilidad del elemento componible es útil cuando se trabaja con contenido desplazable (por ejemplo, LazyColumn) para optimizar la recuperación de datos de los elementos que superan el tamaño de la pantalla.

En esos casos, usa el parámetro minFractionVisible en el modificador onVisibilityChanged para definir la fracción que debe estar en la pantalla para que el elemento componible se marque como visible. Admite valores de punto flotante que van de 0.0f a 1.0f y se establece como 1.0f de forma predeterminada. 1.0f significa que el elemento componible debe ser completamente visible en la pantalla para que se active la devolución de llamada.

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: Sin que se establezca minFractionVisible. Figura 3: Con minFractionVisible establecido como 0.2f.

El ejemplo que se usó anteriormente precarga los bots de Androidify desde la red antes de que el elemento componible sea completamente visible. En la figura 2, el tercer bot no se carga, ya que el elemento componible no es completamente visible. En la figura 3, se establece minFractionVisible, y el tercer bot se carga antes de que sea completamente visible en la pantalla.