当前位置: 首页 > news >正文

Compose笔记(四十七)--SnackbarHost

           这一节主要了解一下Compose中的SnackbarHost,在Jetpack Compose开发中,SnackbarHost是管理Snackbar显示的核心组件,通常与Scaffold结合使用,提供统一的底部消息提示区域。

API
SnackbarHost组件,是一个容器组件,用于在界面中指定Snackbar的显示位置,并将Snackbar与SnackbarHostState关联,使其能够响应状态变化。
构造函数关键参数:
hostState:必填,类型为SnackbarHostState,用于控制Snackbar的显示状态。
modifier:可选,用于设置布局样式。
snackbar:可选,用于自定义Snackbar的样式。
SnackbarHostState状态类,管理Snackbar的状态数据,包括当前显示的Snackbar内容、交互结果等
核心属性和方法:
currentSnackbarData:当前显示的Snackbar数据。
showSnackbar():挂起函数,用于触发Snackbar显示,返回SnackbarResult。
currentSnackbarData?.dismiss():关闭当前显示的Snackbar。

场景:
1 轻量级操作结果提示,如:删除数据后提示 “已删除”、保存设置后提示 “保存成功”等。
2 带交互的二次操作,通过actionLabel添加动作按钮,支持用户执行撤销、重试等操作。
3 长时间提示与手动关闭,使用SnackbarDuration.Indefinite设置无限期显示,配合手动关闭按钮
4 自定义样式适配主题,通过SnackbarHost的snackbar参数自定义外观,如修改背景色、文本大小等,适配应用主题。

栗子:

implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel  
import kotlinx.coroutines.launchclass DeleteViewModel : ViewModel() {var items by mutableStateOf(listOf("项目1", "项目2", "项目3"))private setfun deleteLastItem() {if (items.isNotEmpty()) {items = items.dropLast(1)}}fun undoDelete(deletedItem: String) {items = items + deletedItem}
}@Composable
fun SnackbarExample(viewModel: DeleteViewModel = viewModel()
) {val snackbarHostState = remember { SnackbarHostState() }val scope = rememberCoroutineScope()var lastDeletedItem by remember { mutableStateOf("") }Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) },topBar = {Text(text = "Snackbar示例",modifier = Modifier.padding(20.dp))}) { innerPadding ->Column(modifier = Modifier.fillMaxSize().padding(innerPadding).padding(20.dp),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Text(text = "当前项目: ${viewModel.items.joinToString()}",modifier = Modifier.padding(bottom = 30.dp))Button(onClick = {if (viewModel.items.isNotEmpty()) {lastDeletedItem = viewModel.items.last()viewModel.deleteLastItem()scope.launch {val result = snackbarHostState.showSnackbar(message = "已删除 '$lastDeletedItem'",actionLabel = "撤销",duration = androidx.compose.material3.SnackbarDuration.Short)if (result == androidx.compose.material3.SnackbarResult.ActionPerformed) {viewModel.undoDelete(lastDeletedItem)}}} else {scope.launch {snackbarHostState.showSnackbar(message = "没有可删除的项目",duration = androidx.compose.material3.SnackbarDuration.Short)}}}) {Icon(imageVector = Icons.Default.Delete,contentDescription = "删除",modifier = Modifier.padding(end = 8.dp))Text("删除最后一项")}}}
}
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch@Composable
fun SnackbarExample() {val snackbarHostState = remember { SnackbarHostState() }val scope = rememberCoroutineScope()var inputText by remember { mutableStateOf("") }Scaffold(snackbarHost = {SnackbarHost(snackbarHostState) { data ->Snackbar(action = {if (data.visuals.actionLabel != null) {Button(onClick = { data.performAction() }) {Text(data.visuals.actionLabel ?: "")}}}) {Text(data.visuals.message)}}},topBar = {Text(text = "Snackbar Demo",modifier = Modifier.padding(20.dp))}) { innerPadding ->Column(modifier = Modifier.fillMaxSize().padding(innerPadding).padding(20.dp),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.spacedBy(20.dp, Alignment.CenterVertically)) {OutlinedTextField(value = inputText,onValueChange = { inputText = it },label = { Text("请输入内容") },keyboardOptions = KeyboardOptions(imeAction = ImeAction.Send),keyboardActions = KeyboardActions(onSend = {submitInput(inputText, snackbarHostState, scope)}))Button(onClick = { submitInput(inputText, snackbarHostState, scope) }) {Text("提交")}Button(onClick = {scope.launch {snackbarHostState.currentSnackbarData?.dismiss()}},enabled = snackbarHostState.currentSnackbarData != null) {Text("关闭当前提示")}}}
}private fun submitInput(text: String,snackbarHostState: SnackbarHostState,scope: kotlinx.coroutines.CoroutineScope
) {scope.launch {if (text.isBlank()) {snackbarHostState.showSnackbar(message = "错误:输入不能为空!",duration = androidx.compose.material3.SnackbarDuration.Short)} else {snackbarHostState.showSnackbar(message = "成功:已提交内容 '$text'",actionLabel = "知道了",duration = androidx.compose.material3.SnackbarDuration.Long)}}
}

注意:
1 必须与Scaffold配合使用,SnackbarHost通常作为Scaffold的snackbarHost参数传入,确保Snackbar显示在正确的层级。
2 挂起函数需在协程中调用,showSnackbar()和dismiss()是挂起函数,必须在协程作用域中调用,否则会编译报错。
3 显示时长控制,避免长时间显示,除非提供明确的关闭方式。

http://www.dtcms.com/a/347655.html

相关文章:

  • 14.Shell脚本修炼手册--玩转循环结构(While 与 Until 的应用技巧与案例)
  • 使用sys数据库分析 MySQL
  • 2015-2018年咸海流域1km归一化植被指数8天合成数据集
  • 【大模型应用开发 4.RAG高级技术与实践】
  • LeetCode算法日记 - Day 20: 两整数之和、只出现一次的数字II
  • 《P3623 [APIO2008] 免费道路》
  • Java22 stream 新特性 窗口算子 与 虚拟线程map操作:Gatherer 和 Gatherers工具类
  • 告别静态网页:我用Firefly AI + Spline,构建次世代交互式Web体验
  • 学习Java24天
  • React学习(十二)
  • IDEA相关的设置和技巧
  • C语言第十一章内存在数据中的存储
  • Redis资料
  • JAVA读取项目内的文件或图片
  • springboot项目结构
  • Axure:如何打开自定义操作界面
  • 顺序表(ArrayList)
  • 刷题日记0823
  • [特殊字符] 数据库知识点总结(SQL Server 方向)
  • MySQL:事务管理
  • games101 作业0 环境搭建与熟悉线性代数库
  • H264编解码过程简述
  • 数据结构 -- 哈希表
  • RAGFlow (一) 开发环境搭建
  • imx6ull-驱动开发篇37——Linux MISC 驱动实验
  • [机械结构设计-18]:Solidworks - 特征(Feature)是构成三维模型的基本单元,是设计意图的载体,也是参数化设计的核心。
  • 深入剖析分布式事务的Java实现:从理论到Seata实战
  • c语言中enum与#define的用法区别
  • 算法题(189):食物链
  • 如何利用数据库事务,来防止数据不一致的问题