编写观察实时数据,其中observeAsState不是最佳解决方案

问题描述 投票:0回答:1

所以我有一个 ViewModel,当时间更改时(例如,10:59 -> 11:00),它会将值发布到它的 LiveData 中。 在我的可组合项中,我需要观察 LiveData 和动画背景渐变随时间的变化而变化。 我是这样做的:

@Composable
fun GradientForCurrentTime(viewModel: GradientForCurrentTimeViewModel = viewModel()) {
    var gradient by remember {
        val currentHour = Date().hours
        mutableStateOf(listOf(gradients[currentHour][0], gradients[currentHour][1]))
    }

    viewModel.currentHour.observeForever { hour ->
        val previous = gradient
        val new = listOf(gradients[hour][0], gradients[hour][1])

        val evaluator = ArgbEvaluator()

        val animator: ValueAnimator =
            ValueAnimator.ofObject(evaluator, previous[0].toArgb(), new[0].toArgb()).apply {
                addUpdateListener {
                    val newList = listOf(
                        Color(it.animatedValue as Int), Color(
                            evaluator.evaluate(
                                it.animatedFraction,
                                previous[1].toArgb(),
                                new[1].toArgb()
                            ) as Int
                        )
                    )
                    gradient = newList
                }
                duration = 500
            }
        animator.start()

    }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(
                brush = Brush.verticalGradient(gradient)
            )
    )
}

我的问题来了: 我需要摆脱

observeForever
,因为它显然需要取消订阅,而在这里做到这一点并不那么容易。 另外,我没有看到使用
observeAsState
的最佳方法,因为我已经将
var gradient by remember
作为当前状态来实际绘制渐变。


我当然可以将动画计算移至 ViewModel 中,但它应该是一个选项吗? VeiwModel 应该知道有关动画视图的任何事情吗?

android android-jetpack-compose android-livedata
1个回答
0
投票

感谢@Hack5的评论,我能够解决我的问题并消除

observeForever
的使用:

@Composable
fun GradientForCurrentTime(viewModel: GradientForCurrentTimeViewModel = viewModel()) {

    val currentHour = viewModel.currentHour.observeAsState(Date().hours) //observing current hour from viewModel as state

    var startColor by remember { mutableStateOf(gradients[currentHour.value][0]) } //remembering start and end colors of target gradient
    var endColor by remember { mutableStateOf(gradients[currentHour.value][1]) }
    startColor = gradients[currentHour.value][0] //actually accepting new values for new hour into start and end colors
    endColor = gradients[currentHour.value][1]

    val startColorAnimate by animateColorAsState(
        targetValue = startColor,
        animationSpec = tween(500, easing = LinearEasing), label = "startColorAnimate"
    ) //animate states 

    val endColorAnimate by animateColorAsState(
        targetValue = endColor,
        animationSpec = tween(500, easing = LinearEasing), label = "endColorAnimate"
    )
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(
                brush = Brush.verticalGradient(
                    listOf(
                        Color(startColorAnimate.value), //using the animate states' values
                        Color(endColorAnimate.value)
                    )
                )
            )
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.