Compose中的Dialog
在Jetpack Compose中,Dialog 是用于在屏幕上展示弹出式窗口的组件。Compose 官方提供了两种常见的对话框类型,用于满足不同的需求。
- AlertDialog(常规型)
AlertDialog 是最常用的对话框,主要用于显示一些简单的信息和操作选项(如确认、取消)。它给我们提供了一些基本框架结构。我们只需要以参数的形式传递进去,即可完成简单需求。但填进去后组装的东西真的是我们想要的吗 ~~!?
基本用法
@Composable
fun AlertDialogSample(showDialog: Boolean, onDismiss: () -> Unit) {
if (showDialog) {
AlertDialog(
onDismissRequest = onDismiss,
title = {
Text(text = "提示")
},
text = {
Text("这是一个简单的提示对话框。")
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text("确认")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
}
)
}
}
在这个示例中,通过 showDialog 控制对话框的显示,通过 onDismissRequest 来处理对话框的关闭事件。
- Custom Dialog (洒脱型)
为什么叫他洒脱型弹窗呢。它高度可定制,就是给我们定义了一个框框,里面需要显示什么东西,我们都可以自己填。好处就是太自由了干啥都行,坏处也很明显,用起来太麻烦。内部UI都需要自己一步一步搭建。我们可以使用下面代码来实现一个更加灵活的自定义弹窗。
基本用法:
@Composable
fun CustomDialog(showDialog: Boolean, onDismiss: () -> Unit) {
if (showDialog) {
Dialog(onDismissRequest = onDismiss) {
Surface(
shape = MaterialTheme.shapes.medium,
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "自定义对话框", style = MaterialTheme.typography.h6)
Spacer(modifier = Modifier.height(8.dp))
Text(text = "这里是自定义内容区域。")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = onDismiss) {
Text("关闭")
}
}
}
}
}
}
这里使用了 Dialog 组件和 Surface 容器来自定义对话框的内容和样式。
托福雅思App自定义的Dialog
由于项目中需要用到弹窗的地方很多,而且公共成分很大。每次都自定义弹窗各个地方的组件是非常繁琐的事,所以我们根据Compose的Dialog组件自定义通用Dialog。抽取公共特性,支持仅传递必要关键信息,即可快捷显示出相关弹窗。
- TwoActionDialogWithTitle(自定义通用型)
基本用法
@Composable
fun TwoActionDialogWithTitle(title:String,content:String,leftText:String,rightText:String,onLeftClick:()->Unit,onRightClick:()->Unit,onDismiss: () -> Unit={},cancelAble:Boolean=true) {
Dialog(
onDismissRequest = { onDismiss() },
properties = DialogProperties(dismissOnBackPress = cancelAble, dismissOnClickOutside = cancelAble)
) {
Surface(
shape = RoundedCornerShape(8.dp),
color = IeltsTheme.currentMode.bg_level2_color,
modifier = Modifier
.width(266.dp)
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 15.dp, bottom = 8.dp),
text = title,
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = IeltsTheme.currentMode.text_primary_color,
textAlign = TextAlign.Center,
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, bottom = 20.dp),
text = content,
fontSize = 14.sp,
color = IeltsTheme.currentMode.text_primary_color,
textAlign = TextAlign.Center,
)
Divider(
thickness = 1.dp,
color = IeltsTheme.currentMode.line_hard_color,
modifier = Modifier.fillMaxWidth()
)
Row (
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
){
Box (modifier = Modifier.clickable (
interactionSource = remember { MutableInteractionSource() },
indication=null){
onLeftClick()
}){
Text(
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 30.dp),
text = leftText,
fontSize = 16.sp,
color = IeltsTheme.currentMode.text_secondary_color,
textAlign = TextAlign.Center,
)
}
Divider(
thickness = 44.dp,
color = IeltsTheme.currentMode.line_hard_color,
modifier = Modifier.width(1.dp)
)
Box (modifier = Modifier.clickable (
interactionSource = remember { MutableInteractionSource() },
indication=null){
onRightClick()
}){
Text(
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 30.dp),
text = rightText,
fontSize = 16.sp,
color = IeltsTheme.currentMode.text_brand_color,
textAlign = TextAlign.Center,
)
}
}
}
}
}
}
上面代码向我们展示了自定义Compose中的Dialog的抽取出的公共参数,Dialog自定义配置,及使用等。下面我们介绍一下参数与显示界面功能对应关系
参数与功能对照表
| 参数名 | 解释说明 |
|---|---|
| title | 顶部居中显示的弹窗标题 |
| content | title下面居中显示的弹窗说明文案 |
| leftText | 左侧下面按钮的文案 |
| rightText | 右侧下面按钮的文案 |
| onLeftClick | 左侧下面按钮(leftText文案)点击时触发的事件回调(事件上浮到使用处)。 |
| onRightClick | 右侧下面按钮(rightText文案)点击时触发的事件回调(事件上浮到使用处)。 |
| onDismiss | Dialog弹窗关闭时的回调(事件上浮到调用处,供外界处理相关逻辑) |
| cancelAble | 弹窗(在点击back返回按钮或者点击弹窗外部区域时)是否可以取消 |
- TwoActionDialogWithTitle(支持content显示为自定义组件)
基本用法
@Composable
fun TwoActionDialogWithTitle(title:String,content:@Composable ()->Unit,leftText:String,rightText:String,onLeftClick:()->Unit,onRightClick:()->Unit,onDismiss: () -> Unit={},cancelAble:Boolean=true) {
Dialog(
onDismissRequest = { onDismiss() },
properties = DialogProperties(dismissOnBackPress = cancelAble, dismissOnClickOutside = cancelAble)
) {
Surface(
shape = RoundedCornerShape(8.dp),
color = IeltsTheme.currentMode.bg_level2_color,
modifier = Modifier
.width(266.dp)
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 15.dp, bottom = 8.dp),
text = title,
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = IeltsTheme.currentMode.text_primary_color,
textAlign = TextAlign.Center,
)
content()
Divider(
thickness = 1.dp,
color = IeltsTheme.currentMode.line_hard_color,
modifier = Modifier.fillMaxWidth()
)
Row (
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
){
Box (modifier = Modifier.clickable (
interactionSource = remember { MutableInteractionSource() },
indication=null){
onLeftClick()
}){
Text(
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 30.dp),
text = leftText,
fontSize = 16.sp,
color = IeltsTheme.currentMode.text_secondary_color,
textAlign = TextAlign.Center,
)
}
Divider(
thickness = 44.dp,
color = IeltsTheme.currentMode.line_hard_color,
modifier = Modifier.width(1.dp)
)
Box (modifier = Modifier.clickable (
interactionSource = remember { MutableInteractionSource() },
indication=null){
onRightClick()
}){
Text(
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 30.dp),
text = rightText,
fontSize = 16.sp,
color = IeltsTheme.currentMode.text_brand_color,
textAlign = TextAlign.Center,
)
}
}
}
}
}
}
上面代码与1中几乎一样,但是参数中content字段不是String类型的而是支持用户自定义的可组合函数类型。第二个函数通过重载的方式,向用户提供了自定义Content内容的能力,可以应付更加复杂的UI需求。
参数与功能对照表
| 参数名 | 解释说明 |
|---|---|
| title | 顶部居中显示的弹窗标题 |
| content | 可组合函数,此处可完全自定义content的ui,解决更加复杂的设计需求 |
| leftText | 左侧下面按钮的文案 |
| rightText | 右侧下面按钮的文案 |
| onLeftClick | 左侧下面按钮(leftText文案)点击时触发的事件回调(事件上浮到使用处)。 |
| onRightClick | 右侧下面按钮(rightText文案)点击时触发的事件回调(事件上浮到使用处)。 |
| onDismiss | Dialog弹窗关闭时的回调(事件上浮到调用处,供外界处理相关逻辑) |
| cancelAble | 弹窗(在点击back返回按钮或者点击弹窗外部区域时)是否可以取消 |