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
        )
    }
}

也可以自定义方式绘制,实现SnackbarHost的snackbar

  • 实现代码:
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)
    })
}

自定义方式绘制,实现SnackbarHost的snackbar,也可以用来制作成功失败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)
    })
}

自定义方式绘制,实现SnackbarHost的snackbar,用来制作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也能扩展
相关推荐
_祝你今天愉快5 小时前
UI核心 - UI绘制流程及原理
android
mmsx5 小时前
Android 一个设备多个 App 抢:跨进程共享服务的架构设计
android·kotlin·app
mmsx5 小时前
Android GIS系列 栅格怎么存、格网怎么归算:两个容易混淆的 GIS 链路
android·性能优化·app
陈柒吖5 小时前
安卓代码加固(1):加密DEX
android·前端
mmsx5 小时前
Android GIS系列 串口、蓝牙、USB、网络:一套统一抽象怎么扛住四种通道
android·app·产品
二流小码农5 小时前
鸿蒙开发:ArrayList,可不会让UI更新哦
android·ios·harmonyos
hai_android5 小时前
深入理解 Java 的四种引用:强引用、软引用、弱引用、虚引用
android·kotlin·android jetpack
恋猫de小郭5 小时前
Flutter Golden Tests:给 AI Agent 的 UI 测试系统
android·前端·flutter
知昂七昂6 小时前
AOSP编译:敲下 `lunch xxx-userdebug`,你知道系统偷偷干了什么吗?
android
千里马学框架6 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation