Compose Android Snackbar实现Toast效果

Compose SnackbarHost实现Toast效果

  • 代码如下:
less 复制代码
@Composable
fun SnackbarHost(
    hostState: SnackbarHostState,
    modifier: Modifier = Modifier,
    snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
)
  • SnackbarHostState()控制状态、messaage、时长
kotlin 复制代码
suspend fun showSnackbar(
    message: String,
    actionLabel: String? = null,
    withDismissAction: Boolean = false,
    duration: SnackbarDuration =
        if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite
)
kotlin 复制代码
SnackbarDuration.Indefinite -> Long.MAX_VALUE
SnackbarDuration.Long -> 10000L
SnackbarDuration.Short -> 4000L
  • 为了实现居中效果引入Box,默认是顶部弹出

默认弹出方式效果

  • 实现代码:
ini 复制代码
Box {
    var hostState = SnackbarHostState()
    SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center))
    LaunchedEffect(key1 = "Toast") {
        hostState.showSnackbar(message = "Hello $name!", duration = SnackbarDuration.Short)
    }
}

手动控制关闭弹出效果,一种是actionLabel文字按钮关闭,一种是withDismissAction=true时 icon 删除按钮取消'X'

  • 实现代码:
ini 复制代码
Box {
    var hostState = SnackbarHostState()
    SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center))
    LaunchedEffect(key1 = "Toast") {
        hostState.showSnackbar(
            message = "Hello $name!",
            actionLabel = "确定",
            withDismissAction = true,
            duration = SnackbarDuration.Indefinite
        )
    }
}

也可以自定义方式绘制,实现SnackbarHostsnackbar

  • 实现代码:
ini 复制代码
Box {
    var hostState = SnackbarHostState()
    SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center)) {

        Card(
            Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .padding(horizontal = 8.dp),
            shape = RoundedCornerShape(8.dp),
            colors = CardDefaults.cardColors(
                containerColor = Color(0xFF326C9C),
                contentColor = Color.White
            ),
            elevation = CardDefaults.cardElevation(defaultElevation = 12.dp)
        ) {
            Text(
                text = it.visuals.message,
                modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp)
            )
        }
    }
    LaunchedEffect(key1 = "Toast", block = {
        hostState.showSnackbar(message = "Hello $name!", duration = SnackbarDuration.Short)
    })
}

自定义方式绘制,实现SnackbarHostsnackbar,也可以用来制作成功失败Toast

  1. 不带文字的
  • 实现代码:
ini 复制代码
Box {
  var hostState = SnackbarHostState()
  SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center)) {

      Card(
          Modifier
              .size(96.dp),
          shape = RoundedCornerShape(8.dp),
          colors = CardDefaults.cardColors(
              containerColor = Color.DarkGray,
              contentColor = Color.White
          ),
          elevation = CardDefaults.cardElevation(defaultElevation = 12.dp)
      ) {
          Box(Modifier.fillMaxSize()) {
              Icon(
                  imageVector = Icons.Default.Done,
                  contentDescription = it.visuals.message,
                  modifier = Modifier
                      .align(
                          Alignment.Center
                      )
                      .scale(1.5f)
              )
          }

      }
  }
  LaunchedEffect(key1 = "Toast", block = {
      hostState.showSnackbar(message = "success", duration = SnackbarDuration.Long)
  })
}
  1. 带文字的
  • 实现代码:
ini 复制代码
Box {
    var hostState = SnackbarHostState()
    SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center)) {

        Card(
            Modifier
                .defaultMinSize(minWidth = 96.dp, minHeight = 96.dp),
            shape = RoundedCornerShape(8.dp),
            colors = CardDefaults.cardColors(
                containerColor = Color.DarkGray,
                contentColor = Color.White
            ),
            elevation = CardDefaults.cardElevation(defaultElevation = 12.dp)
        ) {
            Icon(
                imageVector = Icons.Default.Done,
                contentDescription = it.visuals.message,
                modifier = Modifier
                    .align(
                        Alignment.CenterHorizontally
                    )
                    .scale(2.0f)
                    .padding(top = 16.dp)
            )
            Text(
                text = it.visuals.message, modifier = Modifier
                    .align(
                        Alignment.CenterHorizontally
                    )
                    .padding(bottom = 16.dp, top = 16.dp)
            )
        }
    }
    LaunchedEffect(key1 = "Toast", block = {
        hostState.showSnackbar(message = "成功提示", duration = SnackbarDuration.Long)
    })
}

自定义方式绘制,实现SnackbarHostsnackbar,用来制作loading

  • 通过hostState.currentSnackbarData?.dismiss()控制取消,实现代码:
ini 复制代码
Box {
      var hostState = SnackbarHostState()

      SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center)) {
          Card(
              Modifier
                  .size(96.dp),
              shape = RoundedCornerShape(8.dp),
              colors = CardDefaults.cardColors(
                  containerColor = Color.DarkGray,
                  contentColor = Color.White
              ),
              elevation = CardDefaults.cardElevation(defaultElevation = 12.dp)
          ) {
              var isStop by remember {
                  mutableStateOf(false)
              }
              var progress = animateFloatAsState(
                  targetValue = if (isStop) 1f else 0f,
                  animationSpec = infiniteRepeatable(
                      animation = tween(1000, easing = LinearEasing),
                      repeatMode = RepeatMode.Restart
                  ),
                  label = "progress"
              )

              Box(Modifier.fillMaxSize()) {
                  CircularProgressIndicator(
                      progress = progress.value,
                      strokeWidth = 4.dp,
                      strokeCap = StrokeCap.Round,
                      trackColor = Color.Transparent,
                      color = Color.Yellow,
                      modifier = Modifier
                          .size(50.dp)
                          .align(
                              Alignment.Center
                          )
                          .rotate(360 * progress.value)
                  )
//                    Icon(
//                        imageVector = Icons.Default.Refresh,
//                        contentDescription = "progress",
//                        modifier = Modifier.scale(2.0f).rotate(360 * progress.value).align(Alignment.Center)
//                    )
              }
              LaunchedEffect(key1 = "progress", block = {
                  isStop = true
              })
          }
      }
      LaunchedEffect(key1 = "Toast", block = {
          hostState.showSnackbar(message = "成功提示", duration = SnackbarDuration.Indefinite)
      })
      LaunchedEffect(key1 = "dismiss", block = {
          delay(10000L)
          hostState.currentSnackbarData?.dismiss()
      })
  }
总结:有Snackbar特性,也具备Toast功能,复杂Toast也能扩展
相关推荐
安卓修改大师6 小时前
安卓修改大师 vs MT管理器:反编译工具终极对决与全景解析
android·人工智能·机器翻译
程序员小八7777 小时前
从 0 学习 MySQL 索引——7 大核心精讲
android·学习·mysql
雅客李8 小时前
2026云手机低价机型实测 安卓云手机踩坑测评报告
android·智能手机
蓝速科技9 小时前
蓝速科技鸿蒙广告机替代安卓实测:信创系统下的性能与边界评估
android·科技·harmonyos
雅客李9 小时前
2026云手机高负载压力测评 安卓云手机多开实测数据
android·智能手机·php
千里马学框架10 小时前
google官方Perfetto 中使用 AI相关skill
android·人工智能·ai·framework·perfetto·性能·skill
zhangphil12 小时前
Android RecyclerView图像类ViewHolder离屏缓存数量直接增加Java/View对象内存,间接增加Graphics/GL内存
android
众少成多积小致巨12 小时前
Android C++ 编码规范指南
android·c++·google
DavidSu13 小时前
Kotlin协程原理解析
android
lxysbly14 小时前
Android PS3模拟器下载推荐2026|安卓PS3模拟器哪个好?手机玩PS3游戏指南
android·游戏·智能手机