kotlin 合成滑块应响应手动更改和来自外部源的值更改

elcex8rz  于 2023-01-13  发布在  Kotlin
关注(0)|答案(2)|浏览(127)

我想在Jetpack Compose中创建一个滑块,它可以手动操作,并将值存储在DB中。同时,当DB中的值更改时,滑块应该对协程所做的更改做出React。

我只能得到其中一个。下面是对滑块变化做出React的版本(并更新DB和外部源),但当外部源有新值时不更新滑块。如果外部源向DB写入新值,我如何将滑块设置为新值?

@Composable
fun showAllLights(lightsViewModel: LightsViewModel = hiltViewModel()) {

    val allLights = lightsViewModel.lightsAndGroups.collectAsState(initial = emptyList())
    val allLightsByGroupType = allLights.value.filter { it.groupType == "Room" }
    val allGroups = allLightsByGroupType.distinctBy { it.groupId }
    val allLightsGrouped = allLights.value.groupBy {
        it.groupId ?: -1L
    }

    LazyColumn(
        modifier = Modifier
            .fillMaxHeight()
            .fillMaxWidth()
    ) {
        items(allGroups) { currentGroup ->
            val currentGroupId = currentGroup.groupId ?: -1L

            val lightsByKey = allLightsGrouped.filterKeys { it == currentGroupId }
            LazyRow(
                modifier = Modifier
                    .fillMaxHeight()
                    .fillMaxWidth()
            ) {
                lightsByKey.forEach { (key, value) ->
                    items(value) { light ->
                        singleLightCard(
                            light
                        )
                    }
                }
            }
        }
    }
}
@Composable
fun singleLightCard(light: ViewLights, lightsViewModel: LightsViewModel = hiltViewModel()) {

    var initialBrightness = ((light.brightness * 100).toFloat() / 254).roundToInt().toFloat()
    var valueSlider by remember { mutableStateOf(initialBrightness) }

    Card(
        modifier = Modifier
            .height(128.dp)
            .width(144.dp),
    ) {
        Column(
        ) {
            ConstraintLayout(
            ) {
                val (lightBrightnessSlider) = createRefs()

                Slider(
                    modifier = Modifier
                        .constrainAs(lightBrightnessSlider) {
                            bottom.linkTo(
                                parent.bottom
                            )
                        }
                        .height(15.dp),
                    value = valueSlider,
                    onValueChange =  {
                        valueSlider = it
                        val errorMessage = lightsViewModel.onLightBrightnessChange(light, it)
                    },
                    valueRange = 1f..100f,
                )
            }
        }
    }
}
r1wp621o

r1wp621o1#

由于您正在使用最新的亮度值更新数据库,并且每当数据发生更改时数据库都会发射,你不需要创建一个valueSlider状态。你可以简单地使用initialBrightness作为滑块的值,每次DB更新时(通过手动或外部动作)lightsViewModel.lightsAndGroups将发出新的数据集,并且光亮度滑块将使用最新数据更新。
PS:滑块只能有一个真实来源。因此我们将其移到DB中。如果您真的想使用valueSlider状态,您可以将其转换为val,然后使用derivedStateOf代替mutableStateOf

2uluyalo

2uluyalo2#

解决方案是替换

var valueSlider by remember { mutableStateOf(initialBrightness) }

var valueSlider by remember(initialBrightness) { mutableStateOf(initialBrightness) }

相关问题