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 }
                )
            }
        }
    }
}
相关推荐
儿歌八万首8 天前
Jetpack Compose 中 Kotlin 协程的使用
android·ui·kotlin·协程·compose
不用89k2 个月前
Compose Kotlin Multiplatform跨平台基础运行
compose
缘来的精彩3 个月前
Kotlin与Jetpack Compose的详细使用指南
android·kotlin·android studio·compose·viewmodel
清霜之辰3 个月前
安卓 Compose 相对传统 View 的优势
android·内存·性能·compose
tangweiguo030519873 个月前
Android Compose Activity 页面跳转动画详解
android·compose
tangweiguo030519873 个月前
在 Jetpack Compose 中实现 iOS 风格输入框
android·compose
tangweiguo030519873 个月前
Android Compose 权限申请完整指南
compose
tangweiguo030519874 个月前
androd的XML页面 跳转 Compose Activity 卡顿问题
compose
tangweiguo030519874 个月前
Android Material Design 3 主题配色终极指南:XML 与 Compose 全解析
compose