Home > Software engineering >  Can I wrap a LocalDensity.current with remember for a property of a class when I use Jetpack Compose
Can I wrap a LocalDensity.current with remember for a property of a class when I use Jetpack Compose

Time:08-04

1: I know I will get the following error for Code A when I wrap LocalDensity.current with remember. I can't understand fully the error information, could you tell me?

Composable calls are not allowed inside the calculation parameter

2: In Code B, val density is a property of a class WatchState, it's instanced with val watchState = WatchState(...,LocalDensity.current), and watchState is wrapped with remember in fun rememberWatchState().

Will Code B cause error because LocalDensity.current is wraped with remember indirectly ? why?

Code A

@Composable
fun ScreenHome_Watch(){
    val density= remember { LocalDensity.current }
}

Code B

@Composable
fun ScreenHome_Watch(
    watchState:WatchState =  rememberWatchState()
){
    val density= watchState.density
}

@Composable
fun rememberWatchState(): WatchState {
    val context: Context = LocalContext.current
    val temp = loadDBWarningValueWithPreference(context)

    val watchState = WatchState(temp.toFloat(),LocalDensity.current)

    return remember {
        watchState    
    }
}

class WatchState(
    private val alarmValue:Float,
    val density: Density
){
    var radius = 0f
    var isAlarmed = false

    fun updateParameter(size: Size, current:Float){
        radius = size.minDimension / 2 - 10
        isAlarmed = current > alarmValue
    }
}

CodePudding user response:

LocalDensity.current is a Composable function, and the remember function does not provide a composable scope inside its lambda. Therefore, you cannot call LocalDensity.current inside it. It will work if you extract it, though.

val currentDensity = LocalDensity.current
val density = remember { currentDensity }

This is just a demonstration, because the above code is mostly useless, since currentDensity already provides the value that you need.

Moving on, since rememberWatchState is a Composable function, you can call LocalDensity.current and it will get its value, and recompose the whole function when it changes. Using remember { watchState } causes the recomposition to yield the same result, so if the density changes (probably impossible, but just as a side note) the object will not be recreated with the new value, same as the behavior from the code snippet I posted above.

So as a conclusion, using LocalDensity.current outside remember's lambda is the way to solve these kinds of problems.

  • Related