将一次性事件从视图模型发送到可组合以显示对话框的正确方法是什么

Rie*_*key 3 android android-jetpack-compose

我正在使用 Channel 和 Flow 将一次性事件从 ViewModel 发送到 Fragment 和 Activity 以进行 UI 更改,例如显示对话框。当使用可组合项创建 UI 时,这似乎不起作用(或者我可能错过了逻辑中的某些内容)。

在我的应用程序中,当视图模型执行某些任务时,我需要向 UI 发送一次性事件以显示对话框,例如 AlertDialog 可组合项。如官方教程所示,通过使用 MutableState 设置布尔值来关闭该对话框。但是,当我再次发送事件时,MutableState 值保持为 false,并且无法再次显示对话框。

谁能告诉我在 Android Compose 中发送一次性事件和更新 UI 的正确方法。

Fra*_*esc 5

建议使用事件作为状态。

在你的州,你会定义这样的东西

data class MyState(
    val showDialog: Boolean
)
Run Code Online (Sandbox Code Playgroud)

然后,当您想要显示对话框时,您可以更新状态以将标志showDialog设置为true

在 UI 中,您将观察到此标志,当它切换到 时true,您将显示该对话框。当用户关闭对话框时,您在视图模型中调用一个方法,将标志切换回false,如此处所示,因此对话框消失

class MyViewModel : ViewModel() {
    private val _state = MutableStateFlow<MyState>(MyState(showDialog = false))
    val state: StateFlow<MyState>
        get() = _state.asStateFlow()

    // call this when you want to show the dialog
    fun onShowDialog() {
        _state.update { state ->
            state.copy(showDialog = true)
        }
    }

    fun onDismiss() {
        _state.update { state ->
            state.copy(showDialog = false)
        }
    }
}

data class MyState(
    val showDialog: Boolean
)

@Composable
fun MyScreen(
    viewModel: MyViewModel = hiltViewModel()
) {
    val state = viewModel.state.collectAsStateWithLifecycle()
    MyScreen(
        state = state,
        onDismiss = viewModel::onDismiss,
    )
}

@Composable
fun MyScreen(
    state: MyState
    onDismiss: () -> Unit,
) {
    // other stuff

    if (state.showDialog) {
        AlertDialog(
            onDismissRequest = onDismiss,
            buttons = { /*TODO*/ },
            title = { /*TODO*/ },
            text = { /*TODO*/ },
        )
    }
}
Run Code Online (Sandbox Code Playgroud)