一、封装
- 不要用封装 Dialog/AlertDialog 来实现弹窗。Dialog 作为基础组件就是个 Box 毫无意义,不必为了用它而多出很多不必要的代码 。AlertDialog 不基础但点击功能你往容器里传入的自定义界面也能实现。
- 不要用收集 Flow 来实现倒数,collectAsState() 底层用了 remember 持久化,再次弹窗不会从头收集。
Kotlin
/**
* 根布局用Box,该容器与屏幕内容平级,以实现类似对话框弹窗效果。
* @param maxCount 最大计数
* @param isShow 是否显示容器
* @param onDismiss 关闭容器显示
* @param content 容器界面内容
*/
@Composable
fun CountDownContainer(
maxCount: Int,
isShow: Boolean,
onDismiss: () -> Unit,
content: @Composable (Int) -> Unit
) {
var count by remember { mutableIntStateOf(maxCount) }
LaunchedEffect(isShow) {
//it是从0开始正数,+1才能减到0(尽管多数1秒)
repeat(maxCount + 1) {
count = maxCount - it
delay(1000)
}
}
if (count == 0) onDismiss() //数到0就关闭容器
if (isShow) {
content(count)
}
}
二、使用
Kotlin
@Composable
private fun Demo(
) {
var isShow by remember { mutableStateOf(false) }
Button({
isShowDialog = true
}) { Text("点击弹窗") }
CountDownContainer(
maxCount = 5,
isShow = isShow,
onDismiss = { isShow = false }
) {
Box(
modifier = Modifier.size(200.dp).background(Color.Red),
contentAlignment = Alignment.Center
) { Text("$it") }
}
}