跳转到内容

OverlayDialog

OverlayDialog 是 COUI 中的对话框组件,用于显示重要信息、收集用户输入或确认用户操作。对话框会在当前界面上层显示,并支持自定义样式和内容布局。

使用前提

此组件依赖 Scaffold 提供的 COUIPopupHost 以显示弹出内容。必须在 Scaffold 中使用,否则弹出内容无法正常渲染。

引入

kotlin
import io.github.suqi8.coui.kmp.overlay.OverlayDialog

基本用法

OverlayDialog 组件提供了基础的对话框功能:

kotlin
var showDialog by remember { mutableStateOf(false) }

Scaffold {
    TextButton(
        text = "显示对话框",
        onClick = { showDialog = true }
    )

    OverlayDialog(
        title = "对话框标题",
        summary = "这是一个基本的对话框示例,可以包含各种内容。",
        show = showDialog,
        onDismissRequest = { showDialog = false } // Close dialog
    ) {
        TextButton(
            text = "确定",
            onClick = { showDialog = false }, // Close dialog
            modifier = Modifier.fillMaxWidth()
        )
    }
}

属性

OverlayDialog 属性

属性名类型说明默认值是否必须
showBoolean是否显示对话框-
modifierModifier应用于对话框的修饰符Modifier
titleString?对话框的标题null
titleColorColor标题文本的颜色DialogDefaults.titleColor()
summaryString?对话框的摘要说明null
summaryColorColor摘要文本的颜色DialogDefaults.summaryColor()
backgroundColorColor对话框背景色DialogDefaults.backgroundColor()
enableWindowDimBoolean是否启用遮罩层true
onDismissRequest(() -> Unit)?当用户请求关闭(点击遮罩层或返回手势)时触发null
onDismissFinished(() -> Unit)?关闭动画完成后调用;若关闭过程被中途取消(例如 show 被设回 true),则不会触发null
outsideMarginDpSize对话框外部边距DialogDefaults.outsideMargin
insideMarginDpSize内置标题/摘要文本的边距(宽 = 水平内边距,高 = 标题上方内边距);content 插槽不加内边距DialogDefaults.insideMargin
defaultWindowInsetsPaddingBoolean是否应用默认窗口插入内边距true
renderInRootScaffoldBoolean是否在根(最外层)Scaffold 中渲染对话框。为 true 时,对话框覆盖全屏。为 false 时,在当前 Scaffold 的范围内渲染true
maxWidthDp对话框的最大宽度DialogDefaults.MaxWidth
largeScreenBoolean?大屏呈现方式的覆盖项(居中缩放/淡入淡出,而非底部滑入);为 null 时根据窗口尺寸自动判断null
cornerRadiusDp?圆角半径覆盖项;为 null 时使用 DialogDefaults.CornerRadiusnull
content@Composable () -> Unit对话框的内容-

DialogDefaults

属性

属性名类型说明
CornerRadiusDp对话框面板圆角(19.dp)
MaxWidthDp对话框内容最大宽度(392.dp)
outsideMarginDpSize对话框外部默认边距(16, 24)
insideMarginDpSize内置标题/摘要文本的默认边距(24, 24);content 插槽不加内边距
ButtonBarMinHeightDp横向对话框按钮栏的最小高度(58.dp)
ButtonBarInsideMarginPaddingValues横向按钮栏中按钮的内边距(水平 24dp、上 12dp、下 22dp);面板底部留白由按钮自身承担
ButtonBarDividerThicknessDp横向按钮栏分割线的粗细(1.dp)
ButtonBarDividerInsetTopDp横向按钮栏分割线的上内缩(17.dp)
ButtonBarDividerInsetBottomDp横向按钮栏分割线的下内缩(21.dp)

函数

函数名返回类型说明
titleColor()Color获取默认标题颜色
summaryColor()Color获取默认摘要颜色
backgroundColor()Color获取默认对话框背景颜色

进阶用法

居中呈现(大屏)

当窗口宽度不小于 840dp 且高度不小于 480dp 时,对话框会自动居中,并使用缩放/淡入淡出过渡代替底部滑入。可使用 largeScreen 强制指定呈现方式,cornerRadius 覆盖面板圆角:

kotlin
var showDialog by remember { mutableStateOf(false) }

Scaffold {
    TextButton(
        text = "显示居中对话框",
        onClick = { showDialog = true }
    )

    OverlayDialog(
        title = "居中对话框",
        summary = "该对话框始终居中显示,与窗口尺寸无关",
        show = showDialog,
        largeScreen = true, // Force the centered presentation
        cornerRadius = 24.dp, // Override the panel corner radius
        maxWidth = 320.dp,
        onDismissRequest = { showDialog = false }
    ) {
        TextButton(
            text = "确认",
            onClick = { showDialog = false },
            modifier = Modifier.fillMaxWidth()
        )
    }
}

自定义样式对话框

kotlin
var showDialog by remember { mutableStateOf(false) }

Scaffold {
    TextButton(
        text = "显示自定义样式对话框",
        onClick = { showDialog = true }
    )

    OverlayDialog(
        title = "自定义样式",
        summary = "这个对话框使用了自定义颜色和边距",
        show = showDialog,
        onDismissRequest = { showDialog = false }, // Close dialog
        titleColor = Color.Blue,
        summaryColor = Color.Gray,
        backgroundColor = Color(0xFFF5F5F5),
        outsideMargin = DpSize(20.dp, 20.dp),
        insideMargin = DpSize(30.dp, 30.dp)
    ) {
        Text(
            text = "自定义内容区域",
            modifier = Modifier.padding(vertical = 16.dp)
        )
        
        TextButton(
            text = "关闭",
            onClick = { showDialog = false }, // Close dialog
            modifier = Modifier.fillMaxWidth()
        )
    }
}

创建确认对话框

kotlin
var showConfirmDialog by remember { mutableStateOf(false) }
var result by remember { mutableStateOf("") }

Scaffold {
    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        TextButton(
            text = "显示确认对话框",
            onClick = { showConfirmDialog = true }
        )
        
        Text("结果: $result")
    }
    
    OverlayDialog(
        title = "确认操作",
        summary = "此操作不可撤销,是否继续?",
        show = showConfirmDialog,
        onDismissRequest = { showConfirmDialog = false } // Close dialog
    ) {
        Row(
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            TextButton(
                text = "取消",
                onClick = { 
                    result = "用户取消了操作"
                    showConfirmDialog = false // Close dialog
                },
                modifier = Modifier.weight(1f)
            )
            Spacer(Modifier.width(20.dp))
            TextButton(
                text = "确认",
                onClick = { 
                    result = "用户确认了操作"
                    showConfirmDialog = false // Close dialog
                },
                modifier = Modifier.weight(1f),
                colors = ButtonDefaults.textButtonColorsPrimary() // Use theme color
            )
        }
    }
}

带有输入框的对话框

kotlin
var showDialog by remember { mutableStateOf(false) }
var textFieldValue by remember { mutableStateOf("") }

Scaffold {
    TextButton(
        text = "显示输入对话框",
        onClick = { showDialog = true }
    )

    OverlayDialog(
        title = "请输入内容",
        show = showDialog,
        onDismissRequest = { showDialog = false } // Close dialog
    ) {
        TextField(
            modifier = Modifier.padding(bottom = 16.dp),
            value = textFieldValue,
            maxLines = 1,
            onValueChange = { textFieldValue = it }
        )
        
        Row(
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            TextButton(
                text = "取消",
                onClick = { showDialog = false }, // Close dialog
                modifier = Modifier.weight(1f)
            )
            Spacer(Modifier.width(20.dp))
            TextButton(
                text = "确认",
                onClick = { showDialog = false }, // Close dialog
                modifier = Modifier.weight(1f),
                colors = ButtonDefaults.textButtonColorsPrimary() // Use theme color
            )
        }
    }
}

带有表单的对话框

kotlin
var showDialog by remember { mutableStateOf(false) }
var dropdownSelectedOption by remember { mutableStateOf(0) }
var switchState by remember { mutableStateOf(false) }
val dropdownOptions = listOf("选项 1", "选项 2")

Scaffold {
    TextButton(
        text = "显示表单对话框",
        onClick = { showDialog = true }
    )

    OverlayDialog(
        title = "表单对话框",
        show = showDialog,
        onDismissRequest = { showDialog = false } // Close dialog
    ) {
        Card(
            colors = CardDefaults.defaultColors(
                color = COUITheme.colorScheme.secondaryContainer,
            ),
        ) {
            OverlayDropdownPreference(
                title = "下拉选择",
                items = dropdownOptions,
                selectedIndex = dropdownSelectedOption,
                onSelectedIndexChange = { dropdownSelectedOption = it }
            )
            
            SwitchPreference(
                title = "开关选项",
                checked = switchState,
                onCheckedChange = { switchState = it }
            )
        }
        
        Spacer(Modifier.height(12.dp))
        
        Row(
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            TextButton(
                text = "取消",
                onClick = { showDialog = false }, // Close dialog
                modifier = Modifier.weight(1f)
            )
            Spacer(Modifier.width(20.dp))
            TextButton(
                text = "确认",
                onClick = { showDialog = false }, // Close dialog
                modifier = Modifier.weight(1f),
                colors = ButtonDefaults.textButtonColorsPrimary() // Use theme color
            )
        }
    }
}

带有颜色选择器的对话框

kotlin
var showColorDialog by remember { mutableStateOf(false) }
var selectedColor by remember { mutableStateOf(Color.Red) }

Scaffold {
    TextButton(
        text = "选择颜色",
        onClick = { showColorDialog = true }
    )
    
    OverlayDialog(
        title = "选择颜色",
        show = showColorDialog,
        onDismissRequest = { showColorDialog = false } // Close dialog
    ) {
        Column {
            ColorPicker(
                initialColor = selectedColor,
                onColorChanged = { selectedColor = it }
            )
            Spacer(modifier = Modifier.height(16.dp))
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                TextButton(
                    modifier = Modifier.weight(1f),
                    text = "取消",
                    onClick = { showColorDialog = false } // Close dialog
                )
                TextButton(
                    modifier = Modifier.weight(1f),
                    text = "确认",
                    colors = ButtonDefaults.textButtonColorsPrimary(), // Use theme color
                    onClick = {
                        showColorDialog = false // Close dialog
                        // Handle confirm logic
                    }
                )
            }
        }
    }
}

变更日志

基于 Apache-2.0 许可发布