Jetpack Compose:MutableState<Boolean> 未按预期工作

mre*_*elt 6 android state kotlin android-jetpack-compose

在我们的 Android 应用程序中,我们希望将 Compose 引入一个简单的调试屏幕,我们可以在其中启用/禁用 SharedPreferences。我正在尝试使用 Compose 界面来运行它MutableState- 但它并不像我想象的那样工作。我的计划是暂时用于MutableState在 SharedPreferences 中设置布尔值(在稍后迁移到 DataStore 之前)。

这是我的想法:

private class MyOwnState(startWith: Boolean) : MutableState<Boolean> {
    override var value: Boolean = startWith
    override fun component1(): Boolean = value
    override fun component2(): (Boolean) -> Unit = { value = it }
}

// then, in composable:
var value by remember { MyOwnState(false) }
Run Code Online (Sandbox Code Playgroud)

当然,在现实生活中我会覆盖value- 但这个例子就足够了,因为它不起作用。状态更改不会传播,UI 也不会更新。

为了说明这一点,我将代码片段by remember { mutableStateOf(false) }by remember { MyOwnState(false) }. 第一个有效(开关已更新),第二个无效。

完整代码:

@Composable
fun SomeStateExamples() {
    Column {
        SwitchWorks()
        SwitchDoesNotWork()
    }
}

@Composable
fun SwitchWorks() {
    var value by remember { mutableStateOf(false) }
    Switch(checked = value, onCheckedChange = { value = it })
}

@Composable
fun SwitchDoesNotWork() {
    var value by remember { MyOwnState(false) }
    Switch(checked = value, onCheckedChange = { value = it })
}


private class MyOwnState(startWith: Boolean) : MutableState<Boolean> {
    override var value: Boolean = startWith
    override fun component1(): Boolean = value
    override fun component2(): (Boolean) -> Unit = { value = it }
}
Run Code Online (Sandbox Code Playgroud)

第一个开关是可切换的,第二个开关则不可切换:

第一个开关有效,第二个开关无效

我缺少什么?该MutableState接口非常简单且稳定 - 我没有找到任何需要调用的额外方法(又名 invalidate、notifyListeners...)。

感谢您的帮助!

Joh*_*aul 1

不是直接回答,但看看如何mutableStateOf工作,它也在createSnapshotMutableState(value, policy)幕后调用。

因此,我认为仅仅继承MutableState和更改不会导致 Compose 启动重组,从而更新 UI。

我可能会尝试从外部将 UI 状态作为模型传递给 ViewModel 或 LiveData,并改变该模型数据。