es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

onSizeChanged se llama con cada recomposición.

Estoy trabajando en una aplicación de Android basada en la interfaz de usuario (UI) de compose. Necesito obtener el tamaño del compuesto y hacer la obtención del tamaño en cada cambio real. Verifiqué el código base de onSizeChanged. onSizeChanged crea un modificador que extiende OnRemeasuredModifier y almacena el tamaño anterior, pero después de cada recomposición, el tamaño anterior se restablece y esto provoca llamadas infinitas de onSizeChanged. Intenté componer, pero no ayudó. Aquí hay un código de ejemplo:

var counter by remember { mutableStateOf(0) }
LaunchedEffect(key1 = counter, block = {
    delay(1000)
    counter++
})
Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center
) {
    Text(
        modifier = Modifier
            .onSizeChanged {
                it
            }
            .composed {
                Modifier.onSizeChanged {
                    it
                }
            },
        text = "¡Hola, $counter!",
        color = Color.Black
    )
  }
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el tamaño de un componente y hacerlo en cada cambio real de una aplicación Android basada en Compose UI, podemos utilizar el modificador onSizeChanged. Sin embargo, como se menciona en la indicación, esto puede causar un bucle infinito si el tamaño anterior no se almacena correctamente y se restablece después de cada recomposición.

    Para abordar este problema, podemos utilizar una combinación de las funciones remember y LaunchedEffect para realizar un seguimiento del tamaño anterior y actualizarlo solo cuando sea necesario. Aquí hay un ejemplo de fragmento de código para esto:

    var previousSize por remember { mutableStateOf(Size.Zero) }
    var counter por remember { mutableStateOf(0) }
    
    LaunchedEffect(key1 = counter) { // Use key1 to trigger re-composition on counter change
        val newLayout = measureIntrinsicSize()
    
        if (previousSize != newLayout) {
            onSizeChanged(newLayout)
            previousSize = newLayout
        }
    
        delay(1000)
        counter++
    }
    
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "¡Hola, $counter!",
            color = Color.Black
        )
    }
    

    En este código, usamos remember para almacenar el tamaño anterior y el estado del contador. El bloque LaunchedEffect se utiliza para actualizar el tamaño solo cuando sea necesario, es decir, cuando el tamaño actual de la disposición es diferente del tamaño anterior.

    Llamamos a measureIntrinsicSize para obtener el tamaño actual de la disposición y actualizamos el tamaño anterior si ha cambiado. Luego, esperamos 1 segundo utilizando delay para simular un cambio real e incrementar el contador.

    Finalmente, utilizamos las funciones componibles Box y Text para crear la IU. Tenga en cuenta que ya no necesitamos usar el modificador onSizeChanged en la función componible Text, ya que ya estamos realizando un seguimiento del tamaño en el bloque LaunchedEffect.

    Este código debería obtener correctamente el tamaño del componente y actualizarlo solo cuando sea necesario, sin causar un bucle infinito.

Comments are closed.