如何更新jetpack在滑块之外构成滑块状态

问题描述 投票:0回答:3
因此,我正在为我的应用程序使用JetPack组成,并且我的状态在ViewModel中具有浮点值。可以在滑块外更新此值;但是,当抬起手指时,也从滑块中进行(我宁愿在用户仍在滑动手指时进行更新)。 我希望滑块从滑块外部更新时反映其值。但是,当我让滑块内部状态依赖它时,除非从外部状态(没有滑动运动),否则滑块不会更新。我在做什么错?

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

	
android kotlin android-jetpack-compose
3个回答
1
投票
onValueChange

中的模型值。您永远不需要内部状态,因为这会引起歧义。只需遵循“真理的单一来源”原则。

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

ditch内部变量。

无需实施

onValueFinished
。
它将在模型中不断更新,并同时读取合并。另外,如果您不在模型中连续更新它,则在这种情况下,滑块将不会滑动。
另一方面,如果您实现了连续滑动的滑块之类的东西,但仅在用户从滑块上抬起时会更新特定的值,请使用确切的代码,但只需将
remember

应用于内部变量即可。

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

尽管这不是通常的。如果您是出于绩效目的进行的,则不需要。组合是建立在该结构之上的,因此它有效地处理了这些快速状态的变化。
    

我没有测试它,但是如果ViewModel.State是状态流,则认为这样的事情会起作用。
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 } )


而接受的答案有效,并且可能是

方法。 我有一个解决方案无法正常工作的情况。 问题在于,滑块数据深深地嵌套在大型集合和大型数据类的列表中。 要导致ViewModel的状态流进行更改实际上在计算上是昂贵的,在拖动滑块时会创建Laggy UI。 因此,我提出了一个名为

0
投票
,该解决方案仅在滑动完成后才通知ViewModel。 当数据从ViewModel变化时,Slider仍会更新,这是必不可少的。 也许这种模式也将很有用。

here是一种最小的视图模型。 我喜欢它的综合材料,因为我喜欢它的干净。 将其更改为状态流很容易(在其他地方有很多示例)。 如您所见,这只是一个流量变量,只能通过调用the

setSliderPosition()
.
才能更改。

0
投票

这是实现滑块的组合函数。 我已经取出了所有修饰符,以使其变得更简单。 /** * This is a slider that is able to respond to outside changes in its value, * yet only report changes once the slide is complete (user's finger leaves * the slider). * * @param sliderInputValue The value that the slider should display * while not in the middle of a slide. As * this changes this function will recompose, * updating the display appropriately. * * @param setSliderValueFunction Function to call when a slide is complete. * The value of the completed slide in the * range [0..1] is input to the function. */ @Composable fun SliderReportWhenFinished( sliderInputValue: Float, setSliderValueFunction: (Float) -> Unit ) { val slidingPosition = remember { mutableFloatStateOf(0f) } val sliding = remember { mutableStateOf(false) } Slider( value = if (sliding.value) slidingPosition.floatValue else sliderInputValue, onValueChange = { slidingPosition.floatValue = it sliding.value = true }, onValueChangeFinished = { setSliderValueFunction(slidingPosition.floatValue) sliding.value = false } ) } lastly是调用

ReportFinishedSlider()

的代码;我的例子是在主要活动中。 将其安装到您需要的任何地方都应该很容易。 onCreate() 总是欢迎收获。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.