使用三方库
现在已经有第三方库可以使用 https://github.com/brdominguez/compose-sonner
实际它也可以作为SnackBar来使用,不过我的应用情景比较少,就当初toast来使用
我们直接依赖成功后,如下面使用:
val toaster = rememberToasterState()
Toaster(state = toaster)
Button(onClick = { toaster.show("Hello world!") }) {
Text("Show a toast")
}
由于比较常用,所以我下面封装了下:
@Composable
fun rememberToast(): ToasterState {
val isDark = Setting.isUseDarkTheme.currentValue
val toaster = rememberToasterState()
Toaster(state = toaster, maxVisibleToasts = 3, darkTheme = isDark)
return toaster
}
fun ToasterState.showShort(str:String){
show(str, duration = ToasterDefaults.DurationShort)
}
需要使用的话,我就可以下面来使用
Box{
val toaster = rememberToast()
Button(onClick = { toaster.show("Hello world!") }) {
Text("Show a toast")
}
}
其他方案
如果觉得有些没法,使用下面更为简单的taost
看到了一位掘金大佬实现的toast,复制过来了,不过相比上述三方库就有些不够自由 因为它的本质就是靠着Box,将toast组件至于顶层
import androidx.compose.animation.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import kotlin.coroutines.EmptyCoroutineContext
/**
* Toast控制器,参考项目https://github.com/GangJust/AdbHelper
*/
class ComposeToast private constructor() {
private val toastText = mutableStateOf("")
private val toastStatus = mutableStateOf(false)
private var job: Job? = null
companion object {
private val instance = ComposeToast()
fun show(text: String, duration: Long = 2000L, callback: () -> Unit = {}) {
instance.toastText.value = text
if (!instance.isShowing) {
cancel()
instance.job = CoroutineScope(EmptyCoroutineContext).launch {
instance.toastStatus.value = true
delay(duration)
instance.toastStatus.value = false
callback.invoke()
}
}
}
fun cancel() {
val job = instance.job ?: return
if (job.isActive) {
job.cancel()
}
}
fun defaultToastController(): ComposeToast = instance
}
val isShowing
get() = toastStatus.value && job?.isActive ?: false
val text
get() = toastText.value
}
@OptIn(ExperimentalAnimationApi::class)
@Composable //Toast视图容器
fun ComposeToastContainer(
contentAlignment: Alignment = Alignment.BottomCenter,
content: @Composable () -> Unit,
) {
val controller = ComposeToast.defaultToastController()
Box {
content()
BoxWithConstraints(
contentAlignment = contentAlignment,
modifier = Modifier.fillMaxSize(),
content = {
AnimatedVisibility(
visible = controller.isShowing,
enter = scaleIn(),
exit = scaleOut(),
content = {
Card(
elevation = 8.dp,
shape = RoundedCornerShape(16.dp),
backgroundColor = Color.Black,
modifier = Modifier.padding(vertical = 32.dp),
content = {
Text(
text = controller.text,
style = TextStyle.Default.copy(color = Color.White),
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp),
)
}
)
}
)
}
)
}
}
使用示例:
@Composable
fun App(){
val scope = rememberCoroutineScope()
var showTip by remember { mutableStateOf(false) }
MaterialTheme() {
ComposeToastContainer {
//你自己的内容
Row{
//一个按钮测试弹出toast
Button(onClick = {
ComposeToast.show("复制成功!")
}) {
Text("test")
}
}
}
}
}
ComposeToast.show("复制成功!")这个代码可以在任意Compose作用域里使用,也是十分的方便,不需要关心传递什么的
评论区