iOS 风格弹框组件集 (Compose版)

iOSStyleDialogs.kt

复制代码
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties

// 1. 基础确认对话框
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IOSConfirmDialog(
    title: String,
    message: String,
    onDismiss: () -> Unit,
    confirmText: String = "确认",
    cancelText: String = "取消",
    confirmColor: Color = MaterialTheme.colorScheme.primary,
    cancelColor: Color = MaterialTheme.colorScheme.onSurface,
    onConfirm: () -> Unit,
    onCancel: () -> Unit = onDismiss
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(
            dismissOnBackPress = true,
            dismissOnClickOutside = false
        )
    ) {
        Surface(
            shape = RoundedCornerShape(12.dp),
            tonalElevation = 6.dp
        ) {
            Column {
                // 标题
                Text(
                    text = title,
                    style = MaterialTheme.typography.headlineSmall,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(top = 24.dp, start = 24.dp, end = 24.dp)
                )

                // 消息内容
                Text(
                    text = message,
                    style = MaterialTheme.typography.bodyMedium,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(24.dp)
                )

                // 按钮区域
                Divider(color = Color.LightGray.copy(alpha = 0.3f))
                Row {
                    TextButton(
                        onClick = {
                            onCancel()
                            onDismiss()
                        },
                        modifier = Modifier
                            .weight(1f)
                    ) {
                        Text(
                            text = cancelText,
                            color = cancelColor,
                            style = MaterialTheme.typography.labelLarge
                        )
                    }
                    Divider(
                        color = Color.LightGray.copy(alpha = 0.3f),
                        modifier = Modifier
                            .width(1.dp)
                            .height(44.dp)
                    )
                    TextButton(
                        onClick = {
                            onConfirm()
                            onDismiss()
                        },
                        modifier = Modifier
                            .weight(1f)
                    ) {
                        Text(
                            text = confirmText,
                            color = confirmColor,
                            style = MaterialTheme.typography.labelLarge
                        )
                    }
                }
            }
        }
    }
}

// 2. 带输入框的对话框
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IOSInputDialog(
    title: String,
    message: String,
    onDismiss: () -> Unit,
    confirmText: String = "确认",
    cancelText: String = "取消",
    confirmColor: Color = MaterialTheme.colorScheme.primary,
    cancelColor: Color = MaterialTheme.colorScheme.onSurface,
    initialValue: String = "",
    placeholder: String = "请输入",
    onConfirm: (String) -> Unit,
    onCancel: () -> Unit = onDismiss
) {
    var inputValue by remember { mutableStateOf(initialValue) }

    AlertDialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(
            dismissOnBackPress = true,
            dismissOnClickOutside = false
        )
    ) {
        Surface(
            shape = RoundedCornerShape(12.dp),
            tonalElevation = 6.dp
        ) {
            Column {
                // 标题
                Text(
                    text = title,
                    style = MaterialTheme.typography.headlineSmall,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(top = 24.dp, start = 24.dp, end = 24.dp)
                )

                // 消息内容和输入框
                Column(
                    modifier = Modifier.padding(horizontal = 24.dp)
                ) {
                    Text(
                        text = message,
                        style = MaterialTheme.typography.bodyMedium,
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(bottom = 12.dp)
                    )
                    OutlinedTextField(
                        value = inputValue,
                        onValueChange = { inputValue = it },
                        modifier = Modifier.fillMaxWidth(),
                        singleLine = true,
                        placeholder = { Text(placeholder) },
                        shape = RoundedCornerShape(8.dp)
                    )
                }

                // 按钮区域
                Divider(color = Color.LightGray.copy(alpha = 0.3f))
                Row {
                    TextButton(
                        onClick = {
                            onCancel()
                            onDismiss()
                        },
                        modifier = Modifier
                            .weight(1f)
                    ) {
                        Text(
                            text = cancelText,
                            color = cancelColor,
                            style = MaterialTheme.typography.labelLarge
                        )
                    }
                    Divider(
                        color = Color.LightGray.copy(alpha = 0.3f),
                        modifier = Modifier
                            .width(1.dp)
                            .height(44.dp)
                    )
                    TextButton(
                        onClick = {
                            onConfirm(inputValue)
                            onDismiss()
                        },
                        modifier = Modifier
                            .weight(1f)
                    ) {
                        Text(
                            text = confirmText,
                            color = confirmColor,
                            style = MaterialTheme.typography.labelLarge
                        )
                    }
                }
            }
        }
    }
}

// 3. 单按钮提示框
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IOSInfoDialog(
    title: String,
    message: String,
    onDismiss: () -> Unit,
    buttonText: String = "确定",
    buttonColor: Color = MaterialTheme.colorScheme.primary,
    onConfirm: () -> Unit = onDismiss
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(
            dismissOnBackPress = true,
            dismissOnClickOutside = false
        )
    ) {
        Surface(
            shape = RoundedCornerShape(12.dp),
            tonalElevation = 6.dp
        ) {
            Column {
                // 标题
                Text(
                    text = title,
                    style = MaterialTheme.typography.headlineSmall,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(top = 24.dp, start = 24.dp, end = 24.dp)
                )

                // 消息内容
                Text(
                    text = message,
                    style = MaterialTheme.typography.bodyMedium,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(24.dp)
                )

                // 按钮区域
                Divider(color = Color.LightGray.copy(alpha = 0.3f))
                TextButton(
                    onClick = {
                        onConfirm()
                        onDismiss()
                    },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text(
                        text = buttonText,
                        color = buttonColor,
                        style = MaterialTheme.typography.labelLarge
                    )
                }
            }
        }
    }
}

// 预览
@Preview
@Composable
private fun PreviewDialogs() {
    MaterialTheme {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            // 预览确认对话框
            var showConfirm by remember { mutableStateOf(false) }
            Button(onClick = { showConfirm = true }) {
                Text("显示确认对话框")
            }
            if (showConfirm) {
                IOSConfirmDialog(
                    title = "删除确认",
                    message = "确定要删除这条数据吗?删除后不可恢复",
                    onDismiss = { showConfirm = false },
                    onConfirm = { /* 确认操作 */ }
                )
            }

            // 预览输入对话框
            var showInput by remember { mutableStateOf(false) }
            Button(onClick = { showInput = true }) {
                Text("显示输入对话框")
            }
            if (showInput) {
                IOSInputDialog(
                    title = "修改昵称",
                    message = "请输入新的昵称",
                    onDismiss = { showInput = false },
                    onConfirm = { input -> println("新昵称: $input") }
                )
            }

            // 预览提示对话框
            var showInfo by remember { mutableStateOf(false) }
            Button(onClick = { showInfo = true }) {
                Text("显示提示对话框")
            }
            if (showInfo) {
                IOSInfoDialog(
                    title = "操作成功",
                    message = "您的资料已提交审核",
                    onDismiss = { showInfo = false }
                )
            }
        }
    }
}
相关推荐
tangweiguo030519871 天前
Android Compose 权限申请完整指南
compose
tangweiguo030519876 天前
androd的XML页面 跳转 Compose Activity 卡顿问题
compose
tangweiguo030519876 天前
Android Material Design 3 主题配色终极指南:XML 与 Compose 全解析
compose
tangweiguo030519877 天前
Android Compose 中获取和使用 Context 的完整指南
android·compose
tangweiguo030519879 天前
Jetpack Compose 自定义组件完全指南
compose
tangweiguo0305198710 天前
打破界限:Android XML与Jetpack Compose深度互操作指南
android·kotlin·compose
wavky1 个月前
零经验选手,Compose 一天开发一款小游戏!
compose
亚林瓜子1 个月前
Minio安装(Docker Compose方式)
运维·docker·容器·minio·compose
氦客3 个月前
Android Compose 显示底部对话框 (ModalBottomSheet),实现类似BottomSheetDialog的效果
android·dialog·ui·compose·modal·bottomsheet·底部对话框