compose结合 viewmodel 实现 loading ,在@Composable外控制show、dismiss

利用ViewModel封装loading
SnackbarHost制作弹框
SnackbarHostState()控制弹框显示隐藏动作
val hostState = SnackbarHostState()定义在ViewModel中方便控制
class MessageTrans : ViewModel() {
// Hoisted state
val hostState = SnackbarHostState()
@Composable
fun snackProgressInit() {
Box(
Modifier
.fillMaxSize()
.background(
if (hostState.currentSnackbarData?.visuals == null) Color.Transparent else Color(
0x80000000
)
)
) {
SnackbarHost(hostState = hostState, modifier = Modifier.align(Alignment.Center)) {
it.visuals.withDismissAction
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(2000, easing = FastOutSlowInEasing),
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)
.shadow(
2.dp,
RoundedCornerShape(25.dp),
true,
Color.Yellow,
Color.Yellow
)
)
}
LaunchedEffect(key1 = "progress", block = {
isStop = true
})
}
}
}
}
fun show() {
GlobalScope.launch {
hostState.showSnackbar(
message = "加载中...",
duration = SnackbarDuration.Indefinite
)
}
}
fun dismiss() {
GlobalScope.launch {
hostState.currentSnackbarData?.dismiss()
}
}
}
要绘制的根布局初始化snackProgressInit,比如下面这种,目的作为遮罩覆盖在ui层之上
model = MessageTrans()
setContent {
ComposePart1Theme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting10(model)
model.snackProgressInit()
}
}
}
测试调用方式可以是这样的
override fun onResume() {
super.onResume()
model.show()
GlobalScope.launch {
delay(10000)
model.dismiss()
}
}