Search code examples
androidandroid-jetpack-composeandroid-jetpackcomposition

Unable to call @Composable function from remember block


I want to calculate height of Box in a function and I want compose to remember its result and not call that function again. That function has some composable content and therefore it is a @Composable function.

The problem is that, Compose won't let me call this function from remember block.

This is the code that I have:

val coverImageHeightInDp = remember {
    viewModel.calculateTopCoverHeightInDp()
}

Box(modifier = Modifier
    .then(modifier)
    .fillMaxWidth()
    .height(coverImageHeightInDp)
)

And the function in viewModel:

@Composable
fun calculateTopCoverHeightInDp(): Dp {
    val originalImageDimens = Size(1440f, 828f)
    val imageRatio = originalImageDimens.width / originalImageDimens.height
    val configuration = LocalConfiguration.current
    val screenWidthInDp = configuration.screenWidthDp.dp
    return screenWidthInDp / imageRatio
}

How can I code it in a way that the result of this function is remembered and this function is not called again, until screen rotation?

Thanks.


Solution

  • When your computation functions requires some variable from @Composable scope you can just pass the variable you get in composition such as density or configuration

    fun calculateTopCoverHeightInDp(configuration: Configuration): Dp {
        val originalImageDimens = Size(1440f, 828f)
        val imageRatio = originalImageDimens.width / originalImageDimens.height
        val screenWidthInDp = configuration.screenWidthDp.dp
        return screenWidthInDp / imageRatio
    }
    

    And use it as

    val configuration: Configuration = LocalConfiguration.current
    
    val calculatedHeight = remember(configuration){
        calculateTopCoverHeightInDp(configuration)
    }
    

    Also you can check out this answer for difference between Composable and non-Composable functions.

    What are differents between Composable function and normal function in Android?