在 stackoverflow 中,我可以找到许多关于如何在屏幕中运行进程时在屏幕内显示进度条的示例,但我没有找到在屏幕之间显示进度条的示例。
我的一些屏幕可能需要一分钟才能显示何时被呼叫。我希望在等待新屏幕完全显示的同时给用户一些反馈。
我找到了一个部分但非常接近这个问题的解决方案。
我制作了一个调用函数的进度条可组合项,而该函数就是调用新屏幕的函数。确保新屏幕是主安全,以便进度条动画顺利运行。
它仍然不完整,因为即使它有效,进度动画在最终转换期间仍然停止,似乎两个屏幕竞争主线程而不是共享。我还没有找到一种方法可以使新屏幕中的可组合项以低于进度栏的优先级运行。
这是进度条可组合项:
@Composable
fun Progressbar(show: MutableState<Boolean>, myfun: ()->Unit ) {
if (show.value) {
Dialog(
onDismissRequest = { show.value = false },
DialogProperties(
dismissOnBackPress = false,
dismissOnClickOutside = false,
usePlatformDefaultWidth = false,
decorFitsSystemWindows = false
)
) {
val scope = rememberCoroutineScope()
var firstL by remember { mutableStateOf(true) }
var end by remember { mutableStateOf(false) }
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
.background(White, shape = RoundedCornerShape(8.dp))
) {
Text(text = "Loading, please wait.", fontSize = 20.sp, fontWeight = FontWeight.Bold)
CircularProgressIndicator(
// below line is use to add padding
// to our progress bar.
modifier = Modifier
.size(200.dp)
.padding(16.dp),
// below line is use to add color
// to our progress bar.
color = colorResource(id = R.color.purple_200),
// below line is use to add stroke
// width to our progress bar.
strokeWidth = Dp(value = 4F)
)
if (firstL) {
firstL = false
LaunchedEffect(Unit) {
val res = scope.launch {
delay(1000)
myfun()
}
res.join() //Here we set the progress bar to wait for the myfun to finish
end = true //When finished set flag
}
}
if (end) { //When flag is true self turn off Progress bar
show.value = false
}
}
}
}
}
然后使用Composable调用新屏幕:
val showDialog = remember { mutableStateOf(false) }
Button(
onClick = {
showDialog.value = true
//navController.navigate("NewScreen") Instead of calling screen here.
},
colors = ButtonDefaults.buttonColors(Color.Blue)
) {
Text(text = stringResource(R.string.newscreen))
}
//Call screen inside the Progress Bar
Progressbar(show = showDialog) { navController.navigate("NewScreen") }