如何在滑块外更新 Jetpack Compose 滑块状态

How to update jetpack compose slider state outside of the slider

所以,我正在为我的应用程序使用 Jetpack compose,并且我在 viewModel 中有一个带有浮点值的状态。该值可以在滑块外更新;而且当手指被抬起时也会从滑块(我宁愿在用户仍在滑动手指时不更新它)。 我希望滑块在从滑块外部更新时反映该值;但是当我让滑块内部状态依赖于它时,除非从外部状态(没有滑动运动),否则滑块不会更新。我做错了什么?

            val sliderState = mutableStateOf(viewModel.state.value) 
            Slider(
                modifier = Modifier
                    .fillMaxWidth(),
                value = sliderState.value,
                onValueChangeFinished = {
                    viewModel.state.value = sliderState.value
                },
                onValueChange = {
                    sliderState.value = it
                },
            )

只需更新 onValueChange 中的模型值。你永远不需要内部状态,因为这会导致歧义。只要遵循“单一事实来源”原则即可。

使用这个

Slider(
                modifier = Modifier
                    .fillMaxWidth(),
                value = viewModel.state.value,
                onValueChange = {
                    viewModel.state.value = it
                },
            )

放弃内部变量。

无需实施onValueFinished。 它会在模型​​中不断更新,同时在 Composable 中读取。另外,如果你不在模型中持续更新,这种情况下滑块是不会滑动的。

另一方面,如果您要实现类似连续滑动但仅在用户将手指从滑块上移开时更新特定值的滑块,请使用您的确切代码,但只需应用 remember 到你的内部变量。

val sliderState = remember { mutableStateOf(viewModel.state.value) }

虽然,这不是通常需要的东西。如果您出于性能目的而这样做,则不需要。 Compose 建立在这个结构之上,因此它可以有效地处理这些快速的状态变化。

我没有测试它,但我认为如果 viewModel.state 是一个 StateFlow,这样的东西会起作用。

val sliderState = viewModel.state.collectAsState()
val localState = remember { mutableStateOf(sliderState.value) }
Slider(
    modifier = Modifier
        .fillMaxWidth(),
    value = localState.value,
    onValueChangeFinished = {
        viewModel.state.value = localState.value
    },
    onValueChange = {
        localState.value = it
    }
)