Search code examples
androidkotlinandroid-jetpack-composecompose-recomposition

onSizeChanged getting called with every recomposition


I'm working on compose UI-based android app. I need to get the size of composable and do get size on every real change. I checked the base code of onSizeChanged. onSizeChanged creates modifier extending OnRemeasuredModifier and stores previous size but after every recomposition, the previous gets reset and this cause infinite calls of onSizeChanged. I tried composed but that didn't help. Here is a sample code:

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 = "Hello, $counter!",
        color = Color.Black
    )
  }
}

Solution

  • The solution I implemented is to remember onSizeChanged Modifier to save the previous size. but I'm not certain that this is the correct way.

    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
                    }
                }
                .remembered {
                    Modifier.onSizeChanged {
                        it
                    }
                },
            text = "Hello, $counter!",
            color = Color.Black
        )
      }
    }
    

    I tried composed but that didn't help. So I created the remembered function:

    @Composable
    fun Modifier.remembered(modifier: () -> Modifier): Modifier {
        val rememberedModifier = remember {
            modifier()
        }
        return then(rememberedModifier)
    }