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 registrar estadísticas, administrar el estado de la IU y optimizar los recursos reproduciendo o pausando automáticamente el 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 que admite composición. 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 de base para onVisibilityChanged. El modificador es similar a onGloballyPositioned, pero ofrece un mejor rendimiento y una mayor flexibilidad.

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

Realiza un seguimiento de los cambios de visibilidad con onVisibilityChanged

Saber 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 recuperar previamente datos de la red solo cuando el elemento es visible) o incluso activar eventos (reproducir o pausar videos).

Para recibir una notificación cuando cambie 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 control más detallado sobre cuándo se debe activar la devolución de llamada de visibilidad.

Al igual que con cualquier otro modificador, la secuenciación es importante 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 quieras activar una acción solo después de que un elemento haya sido visible para el usuario durante un período determinado. 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 que admite composición deja de ser visible antes de que se cumpla la duración, se restablece el temporizador. El valor predeterminado es 0 milisegundos.

En el siguiente fragmento, se cambia el fondo a morado después de que el elemento componible haya sido 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 haya estado en pantalla durante 3 segundos de forma continua.

Establece una fracción visible mínima

Establecer una fracción mínima visible 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 pantalla para que el elemento componible se marque como visible. Admite valores de número 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 estar 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 en 0.2f.

En el ejemplo que se usó antes, se precargan 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 que admite composición 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.