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也能扩展
相关推荐
雨白8 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹10 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空11 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭12 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日13 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安13 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑13 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟17 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡18 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0018 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体