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
- 不带文字的
- 实现代码:
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)
})
}
- 带文字的
- 实现代码:
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()
})
}