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也能扩展
相关推荐
Kapaseker1 小时前
你不看会后悔的2025年终总结
android·kotlin
alexhilton4 小时前
务实的模块化:连接模块(wiring modules)的妙用
android·kotlin·android jetpack
ji_shuke4 小时前
opencv-mobile 和 ncnn-android 环境配置
android·前端·javascript·人工智能·opencv
sunnyday04266 小时前
Spring Boot 项目中使用 Dynamic Datasource 实现多数据源管理
android·spring boot·后端
幽络源小助理8 小时前
下载安装AndroidStudio配置Gradle运行第一个kotlin程序
android·开发语言·kotlin
inBuilder低代码平台8 小时前
浅谈安卓Webview从初级到高级应用
android·java·webview
豌豆学姐8 小时前
Sora2 短剧视频创作中如何保持人物一致性?角色创建接口教程
android·java·aigc·php·音视频·uniapp
白熊小北极8 小时前
Android Jetpack Compose折叠屏感知与适配
android
HelloBan8 小时前
setHintTextColor不生效
android
洞窝技术10 小时前
从0到30+:智能家居配网协议融合的实战与思考
android