Jetpack 组合 uiState 中的更改不会触发重组

Tim*_*dia 5 android state android-jetpack android-jetpack-compose

我想我还没有完全理解组合状态是如何工作的。当 uiState 中的项目发生更改时,我无法触发重组。

我正在构建一个需要通知访问的应用程序,因此我将用户导航到设置,并且在用户授予权限后,他们必须导航回该应用程序。这就是我想触发重组的地方。

我在 onResume 工作中进行了权限检查,并且 uiState 中的变量发生了变化,但没有调用重组。我在这里缺少什么?

可组合的

@Composable
private fun MainLayout(viewModel: SetupViewModel){
    val uiState = viewModel.uiState.collectAsState()
    SetupItem(
        title = "Notification access",
        summary = if(uiState.value.hasNotificationPermission) stringResource(R.string.granted) else stringResource(R.string.not_granted){}
}
Run Code Online (Sandbox Code Playgroud)

设置UiState.kt

data class SetupUiState(
    var hasNotificationPermission: Boolean = false
)
Run Code Online (Sandbox Code Playgroud)

我知道一个事实hasNotificationPermission被设置为 true,但 SetupItem 中的摘要不会更新。我该如何做到这一点?

Jan*_*ína 13

这里的问题是该hasNotificationPermission字段是可变的(var而不是可变的val)。Compose 不跟踪内部字段的更改。您在这里有两个选择:

  1. 修改整个SetupUiState,假设您在ViewModel中使用StateFlow,它可能如下所示:
    fun setHasNotificationPermission(value: Boolean) {
        uiState.update { it.copy(hasNotificationPermission = value) }
    }
    
    Run Code Online (Sandbox Code Playgroud) 您还应该从 var 更改hasNotificationPermission为 val。
  2. 您可以利用 composeState并执行以下操作:
    class SetupUiState(
        initialHasPermission: Boolean = false
    ) {
        var hasNotificationPermission: Boolean by mutableStateOf(initialHasPermission)
    }
    
    Run Code Online (Sandbox Code Playgroud) 有了这个,您就可以简单地执行操作uiState.hasNotificationPermission = value,并且将通知合成,因为它会State自动跟踪实例。