前言
除了布局组件外,Jetpack Compose 还提供了一系列其他常用的 UI 组件。
https://developer.android.google.cn/jetpack/compose/components?hl=zh-cn
https://developer.android.google.cn/courses/pathways/compose?hl=zh-cn
消息框
提示消息有以下几种方式
Toast
Snackbar
自定义组件
Toast
组件化
1 | import android.annotation.SuppressLint |
调用
1 | var showToast by remember { mutableStateOf(false) } |
组件内方法
1 | val context = LocalContext.current |
Snackbar
基本示例
1 |
|
使用snackbarHost
1 | val scope = rememberCoroutineScope() |
ViewModel 中消息提示
在 Jetpack Compose 中,通常不建议直接在 ViewModel 中处理 UI 相关操作(如弹出消息提示),因为这违反了单一职责原则和关注点分离。
ViewModel 应该只负责管理数据和业务逻辑,而 UI 相关的操作应该由 Composable 组件处理。
正确的做法是:
- 在 ViewModel 中定义一个状态来表示是否需要显示消息
- 在 Composable 中观察这个状态
- 当状态变化时,在 Composable 中显示消息提示
以下是一个实现示例:
事件类
首先,创建一个密封类来表示 UI 事件:
1 | sealed class UiEvent { |
发送事件
然后,在 ViewModel 中使用 Channel
或 StateFlow
来发送事件:
1 | import androidx.lifecycle.ViewModel |
事件接收
在 Composable 中观察事件并显示消息:
1 | import androidx.compose.foundation.layout.Box |
自定义样式
1 | import androidx.compose.foundation.background |
组件引用
直接使用
1 | MsgReceiveComp(loginViewModel) |
这种方式遵循了 Jetpack 的最佳实践,保持了 ViewModel 和 UI 层的分离,同时能够从 ViewModel 触发消息提示。
如果你需要使用 Toast 而不是 Snackbar,方法类似,只需在 Composable 中收到事件时调用 Toast.makeText()
即可。
全局使用
上面说的是组件内用,但是每个组件都这样整,优点繁琐,并且位置也不一定是整个屏幕,所以这里配置全局使用。
在App的组件中添加接收组件
1 | import androidx.compose.foundation.layout.Box |
全局变量中添加
1 | object CommonData { |
使用的时候这样调用
1 | CommonData.appViewModel?.showSnackbarAction("未选择教材") |
对话框
1 | Dialog(onDismissRequest = { /* 关闭对话框事件 */ }) { |