Android中使用Compose实现各种样式Dialog

发布于:2025-08-18 ⋅ 阅读:(13) ⋅ 点赞:(0)

Android中使用Compose实现各种样式Dialog

在这里插入图片描述

1.前言:

很早之前也写过几篇学习Compose基础的文章,最近看github开源项目使用了十来个开源项目,发现基本上ui使用的都是Compose,然后又开发了几个Ai应用,所以决定重新回顾一下之前的compose基础,最后在实际项目中慢慢逐步更换,毕竟这已经是大势所趋,当然这个根据个人情况进行,不强求,我是因为有很多compose基础,公司项目也需要新技术,索性就直接使用最新的MVI+Compose,好了直接上代码.

2.添加Compose依赖:

2.1 libs.versions.toml:

[versions]
agp = "8.10.1"
kotlin = "2.0.21"
coreKtx = "1.16.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.9.1"
activityCompose = "1.10.1"
composeBom = "2024.09.00"
material3 = "1.1.0"
material = "1.8.3"
materialIconsExtendedVersion = "1.7.8"
androidxMaterial3 = "1.1.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-material = { module = "androidx.compose.material:material", version.ref = "material" }
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsExtendedVersion" }

2.2 App目录下的build.gradle:

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
    implementation(libs.androidx.material.icons.extended)
}

3.简单样式的Dialog:

@Composable
fun SampleDialog(
    showDialog: Boolean,
    onDismiss:() -> Unit,
    onConfirm:() -> Unit
){
    if(showDialog){
        Dialog(onDismissRequest = onDismiss){
            androidx.compose.material3.Surface(
                shape = RoundedCornerShape(10.dp),
                color = MaterialTheme.colorScheme.surface
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth(0.8f)
                        .heightIn(min = 200.dp, max = 400.dp)
                        .padding(16.dp)
                ) {
                    Text(
                        text = "确认操作",
                        style = MaterialTheme.typography.headlineSmall
                    )
                    Spacer(modifier = Modifier.height(16.dp))
                    Text(
                        text = "您确定要执行此操作吗?",
                        style = MaterialTheme.typography.bodyMedium
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Row(
                        modifier = Modifier.align(Alignment.End),
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        TextButton(onClick = onDismiss) {
                            Text("取消")
                        }
                        TextButton(onClick = onConfirm) {
                            Text("确认")
                        }
                    }
                }
            }
        }
    }
}

4.实现效果截图:

在这里插入图片描述

5.自定义样式的Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

/**
 * @author: njb
 * @date:   2025/8/16 22:19
 * @desc:   描述
 */
@Composable
fun CustomStyledDialog(
    showDialog: Boolean,
    onDismiss: ()-> Unit
){
    if(showDialog){
        Dialog(onDismissRequest = onDismiss){
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(300.dp)
                    .padding(8.dp),
                shape = RoundedCornerShape(10.dp),
                colors = CardDefaults.cardColors(
                    containerColor = Color(0xFFE3F2FD)
                )
            ) {
                Column(
                    modifier = Modifier.padding(16.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ) {
                    Icon(
                        Icons.Default.CheckCircle,
                        contentDescription = "成功",
                        tint = Color(0xFF2E7D32),
                        modifier = Modifier.size(64.dp)
                    )

                    Spacer(modifier = Modifier.height(16.dp))

                    Text(
                        text = "支付成功",
                        style = MaterialTheme.typography.headlineSmall.copy(
                            color = Color(0xFF2E7D32)
                        )
                    )

                    Spacer(modifier = Modifier.height(8.dp))

                    Text(
                        text = "您的订单已成功支付",
                        style = MaterialTheme.typography.bodyMedium
                    )

                    Spacer(modifier = Modifier.height(24.dp))

                    Button(
                        onClick = onDismiss,
                        colors = ButtonDefaults.buttonColors(
                            containerColor = Color(0xFF2E7D32)
                        ),
                        modifier = Modifier.fillMaxWidth(1f)
                    ) {
                        Text("确定")
                    }
                }
            }

        }
    }
}

6.实现效果截图:

在这里插入图片描述

7.Loading样式DIalog:

package com.example.composedialogdemo.dialog

import androidx.activity.result.IntentSenderRequest
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

/**
 * @author: njb
 * @date:   2025/8/16 20:26
 * @desc:   描述
 */
@Composable
fun LoadingDialog(
    showDialog: Boolean,
    onDismissRequest: () -> Unit,
    message : String = "正在加载中..."
){
    if(showDialog){
        Dialog(
            onDismissRequest = onDismissRequest) {
            Surface(
                shape = MaterialTheme.shapes.medium,
                modifier = Modifier
                    .width(200.dp)
                    .height(150.dp),
                color =MaterialTheme.colorScheme.surface
            ){
                Column(
                    modifier = Modifier.padding(16.dp),
                    horizontalAlignment =   Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ){
                    CircularProgressIndicator()
                    Spacer(modifier = Modifier.height(16.dp))
                    Text(text = message)
                }
            }
        }
    }
}

8.实现效果截图:

在这里插入图片描述

9.进度条样式Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

/**
 * @author: njb
 * @date:   2025/8/16 22:06
 * @desc:   描述
 */
@Composable
fun ProgressDialog(
    showDialog: Boolean,
    message: String = "下载中...",
    progress: Float
){
    if (showDialog) {
        Dialog(onDismissRequest = {}) {
            // 添加卡片阴影和圆角
            Card(
                shape = RoundedCornerShape(12.dp),
                elevation = CardDefaults.cardElevation(defaultElevation = 8.dp),
                modifier = Modifier
                    .width(300.dp)
                    .background(Color.Transparent)
            ) {
                // 添加内边距
                Column(
                    modifier = Modifier
                        .padding(20.dp)
                        .fillMaxWidth(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ) {
                    // 标题文字
                    Text(
                        text = message,
                        style = MaterialTheme.typography.titleMedium,
                        color = MaterialTheme.colorScheme.onSurface,
                        modifier = Modifier.padding(bottom = 16.dp)
                    )

                    // 优化的进度条
                    LinearProgressIndicator(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(6.dp),
                        color = MaterialTheme.colorScheme.primary,
                        trackColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f),
                        // 将progress参数改为lambda形式
                        progress = { progress }
                    )

                    // 进度百分比
                    Text(
                        text = "${(progress * 100).toInt()}%",
                        style = MaterialTheme.typography.bodyLarge,
                        color = MaterialTheme.colorScheme.primary,
                        modifier = Modifier
                            .padding(top = 12.dp)
                            .align(Alignment.End)
                    )
                }
            }
        }
    }
}

10.实现效果截图:

在这里插入图片描述

11.底部样式Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

/**
 * @author: njb
 * @date:   2025/8/16 20:12
 * @desc:   描述
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomSheetDialog(
showDialog: Boolean,
onDismiss:() -> Unit
){
    if(showDialog){
        ModalBottomSheet(
            onDismissRequest = onDismiss,
            sheetState = rememberModalBottomSheetState()
        ){
            Column(
            modifier = Modifier.fillMaxWidth()
            .padding(16.dp)
            ) {
                Text(
                    text = "底部对话框",
                    style = MaterialTheme.typography.headlineSmall)
            }
            Spacer(modifier = Modifier.height(16.dp))
            Text("这是一个从底部弹出的对话框示例")
            Spacer(modifier = Modifier.height(16.dp))
            Button(
                onClick = onDismiss,
                modifier = Modifier.fillMaxWidth()
            ) {
               Text("关闭")
            }
        }
    }
}

12.实现效果截图:

在这里插入图片描述

13.全屏样式Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties

/**
 * @author: njb
 * @date:   2025/8/17 0:07
 * @desc:   描述
 */
@Composable
fun FullScreenDialog(
    showDialog: Boolean,
    onDismiss: () -> Unit
) {
    if (showDialog) {
        Dialog(
            onDismissRequest = onDismiss,
            properties = DialogProperties(usePlatformDefaultWidth = false)
        ) {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                Column(
                    modifier = Modifier.padding(16.dp)
                ) {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text    (
                            text = "全屏对话框",
                            style = MaterialTheme.typography.headlineMedium
                        )
                        IconButton(onClick = onDismiss) {
                            Icon(Icons.Default.Close, contentDescription = "关闭")
                        }

                    }
                    Spacer(modifier = Modifier.height(16.dp))
                    Text("这是一个全屏对话框的示例")
                }
            }
        }
    }
}

14.实现效果截图:

在这里插入图片描述

15.带图标样式的Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Update
import androidx.compose.material.icons.filled.Upgrade
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp

/**
 * @author: njb
 * @date:   2025/8/16 20:52
 * @desc:   描述
 */
@Composable
fun IconSimpleDialog(
    showDialog: Boolean,
    onDismiss:() -> Unit
){
    if (showDialog) {
        AlertDialog(
            onDismissRequest = onDismiss,
            shape = RoundedCornerShape(8.dp),
            icon = {
                Icon(Icons.Default.Info,
                contentDescription = "提示图标")
            },
            title = { Text("版本更新")},
            text = {Text("这个版本修改一些已知问题和用户体验!")},
            confirmButton = {
                TextButton(onClick = onDismiss) {
                    Text("立即更新")
                }
            }
        )
    }
}

16.实现效果截图:

在这里插入图片描述

17.输入框样式的DIalog:

package com.example.composedialogdemo.dialog

import android.R.attr.text
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

/**
 * @author: njb
 * @date:   2025/8/16 21:46
 * @desc:   描述
 */
@Composable
fun InputDialogExample(
    showDialog: Boolean,
    onDismiss:() -> Unit,
    onConfirm: (String) -> Unit
){
    var text by remember { mutableStateOf("") }
    if(showDialog){
        Dialog(onDismissRequest = onDismiss) {
            Surface(
                shape = MaterialTheme.shapes.medium,
                color = MaterialTheme.colorScheme.surface,
            ){
                Column(modifier = Modifier.padding(16.dp)) {
                    Text(
                        text = "请输入内容",
                        style = MaterialTheme.typography.headlineSmall,
                    )
                    Spacer(modifier = Modifier.height(16.dp))
                    OutlinedTextField(
                        value = text,
                        onValueChange = { text= it},
                        label = {Text("请输入内容")},
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Row (
                        modifier = Modifier.align(Alignment.End),
                        horizontalArrangement =Arrangement.spacedBy(8.dp)
                    ){
                        TextButton(onClick = onDismiss) {
                            Text("取消")
                            onDismiss
                        }
                        TextButton(onClick = {onConfirm(text) } ,
                            enabled =text.isNotBlank()
                        ){
                            Text("确认")
                        }
                    }
                }
            }
        }
    }
}

18.效果截图:

在这里插入图片描述

19.列表样式Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog

/**
 * @author: njb
 * @date:   2025/8/17 0:46
 * @desc:   描述
 */
@Composable
fun ListSelectionDialog(
    showDialog : Boolean,
    onDismiss:() -> Unit,
    title: String,
    items: List<String>,
    onItemSelected:(Int) -> Unit
){
    if(showDialog){
        Dialog(onDismissRequest = onDismiss) {
            Surface(
                shape = RoundedCornerShape(10.dp),
                modifier = Modifier.width(300.dp)
            ) {
                Column {
                    Text(
                        text = title,
                        style = MaterialTheme.typography.headlineSmall,
                        modifier = Modifier.padding(10.dp)
                    )
                    HorizontalDivider()
                    LazyColumn(
                        modifier = Modifier.heightIn(max = 400.dp)
                    ) {
                        items(items.size) { index ->
                            TextButton(
                                onClick = {
                                    onItemSelected(index)
                                    onDismiss()
                                },
                                modifier = Modifier.fillMaxWidth()
                            ) {
                                Text(
                                    text = items[index],
                                    modifier = Modifier.padding(vertical = 8.dp),
                                    textAlign = TextAlign.Start
                                )
                            }

                            if (index < items.lastIndex) {
                                HorizontalDivider()
                            }
                        }
                    }
                }
            }
        }
    }
}

20.效果截图:

在这里插入图片描述

21.单选样式的DIalog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

/**
 * @author: njb
 * @date:   2025/8/17 0:48
 * @desc:   描述
 */
@Composable
fun SingleChoiceDialog(
    showDialog: Boolean,
    onDismiss:() -> Unit,
    onConfirm:(Int) -> Unit
){
    val options = listOf("选项1", "选项2", "选项3", "选项4")
    var selectedOption by remember { mutableIntStateOf(0) }
    if (showDialog) {
        AlertDialog(
            onDismissRequest = onDismiss,
            title = { Text("请选择一个选项") },
            text = {
                Column {
                    options.forEachIndexed { index, option ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable { selectedOption = index }
                                .padding(vertical = 8.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(
                                selected = selectedOption == index,
                                onClick = { selectedOption = index }
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                            Text(text = option)
                        }
                    }
                }
            },
            confirmButton = {
                TextButton(onClick = { onConfirm(selectedOption) }) {
                    Text("确定")
                }
            },
            dismissButton = {
                TextButton(onClick = onDismiss) {
                    Text("取消")
                }
            }
        )
    }
}

22.实现效果:

在这里插入图片描述

23.多选样式的Dialog:

package com.example.composedialogdemo.dialog

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.AlertDialog
import androidx.compose.material.Checkbox
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

/**
 * @author: njb
 * @date:   2025/8/17 0:49
 * @desc:   描述
 */
@Composable
fun MultiChoiceDialog(
    showDialog: Boolean,
    onDismiss:() -> Unit,
    onConfirm: (List<Int>) -> Unit
){
    val options = listOf("选项1", "选项2", "选项3", "选项4")
    val selectedOptions = remember { mutableStateListOf<Int>() }

    if(showDialog){
        AlertDialog(
            onDismissRequest = onDismiss,
            title = { Text("请选择多个选项") },
            text = {
                Column {
                    options.forEachIndexed { index, option ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    if (selectedOptions.contains(index)) {
                                        selectedOptions.remove(index)
                                    } else {
                                        selectedOptions.add(index)
                                    }
                                }
                                .padding(vertical = 8.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Checkbox(
                                checked = selectedOptions.contains(index),
                                onCheckedChange = { isChecked ->
                                    if (isChecked) {
                                        selectedOptions.add(index)
                                    } else {
                                        selectedOptions.remove(index)
                                    }
                                }
                            )
                            Spacer(modifier = Modifier.width(8.dp))
                            Text(text = option)
                        }
                    }
                }
            },
            confirmButton = {
                TextButton(
                    onClick = { onConfirm(selectedOptions.toList()) },
                    enabled = selectedOptions.isNotEmpty()
                ) {
                    Text("确定")
                }
            },
            dismissButton = {
                TextButton(onClick = onDismiss) {
                    Text("取消")
                }
            }
        )
    }

}

24.实现效果:

在这里插入图片描述

25.日期样式Dialkog:

package com.example.composedialogdemo.dialog

import android.app.DatePickerDialog
import android.icu.util.Calendar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import java.time.LocalDate

/**
 * @author: njb
 * @date:   2025/8/17 0:23
 * @desc:   描述
 */
@Composable
fun DatePickerDialog(
    showDialog: Boolean,
    onDismiss: () -> Unit,
    onDateSelected: (LocalDate) -> Unit
) {
    val context = LocalContext.current
    val calendar = Calendar.getInstance()
    val year = calendar.get(Calendar.YEAR)
    val month = calendar.get(Calendar.MONTH)
    val day = calendar.get(Calendar.DAY_OF_MONTH)
    val dataPicker = remember {
        DatePickerDialog(
            context,
            { _, selectYear, selectMonth, selectDay ->
                onDateSelected(LocalDate.of(selectYear, selectMonth + 1, selectDay))
            },
            year,
            month,
            day
        )
    }
    if (showDialog) {
        DisposableEffect(Unit) {
            dataPicker.show()
            onDispose {
                dataPicker.dismiss()
            }
        }
    }
}

26.实现效果:

在这里插入图片描述

27.时间样式Dialog:

package com.example.composedialogdemo.dialog

import android.app.TimePickerDialog
import android.icu.util.Calendar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import java.time.LocalTime

/**
 * @author: njb
 * @date:   2025/8/17 0:36
 * @desc:   描述
 */
@Composable
fun TimePickerDialogSample(
    showDialog: Boolean,
    onDismiss: () -> Unit,
    onTimeSelected: (LocalTime) -> Unit
) {
    val context = LocalContext.current
    val calendar = Calendar.getInstance()
    val hour = calendar.get(Calendar.HOUR_OF_DAY)
    val minute = calendar.get(Calendar.MINUTE)
    val timePicker = remember {
        TimePickerDialog(
            context,
            { _, selectedHour, selectedMinute ->
                onTimeSelected(LocalTime.of(selectedHour, selectedMinute))
            },
            hour,
            minute,
            true // 24小时制
        )
    }
    if (showDialog) {
        DisposableEffect(Unit) {
            timePicker.show()
            onDispose {
                timePicker.dismiss()
            }
        }
    }
}

28.实现效果:

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1013315f66724de69e821aca63110e34.png)

29.完整测试代码:

package com.example.composedialogdemo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.composedialogdemo.dialog.BottomSheetDialog
import com.example.composedialogdemo.dialog.CustomStyledDialog
import com.example.composedialogdemo.dialog.DatePickerDialog
import com.example.composedialogdemo.dialog.FullScreenDialog
import com.example.composedialogdemo.dialog.IconSimpleDialog
import com.example.composedialogdemo.dialog.InputDialogExample
import com.example.composedialogdemo.dialog.ListSelectionDialog
import com.example.composedialogdemo.dialog.LoadingDialog
import com.example.composedialogdemo.dialog.LocationDialog
import com.example.composedialogdemo.dialog.MultiChoiceDialog
import com.example.composedialogdemo.dialog.ProgressDialog
import com.example.composedialogdemo.dialog.SampleDialog
import com.example.composedialogdemo.dialog.SingleChoiceDialog
import com.example.composedialogdemo.dialog.TimePickerDialogSample
import com.example.composedialogdemo.ui.theme.ComposeDialofDemoTheme
import kotlinx.coroutines.delay
import java.time.LocalDate
import java.time.LocalTime

class   MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            ComposeDialofDemoTheme {
                var showBottomSheet by remember { mutableStateOf(false) }
                var showLoadingDialog by remember { mutableStateOf(false) }
                var showLocationDialog by remember { mutableStateOf(false) }
                var showIconDialog by remember { mutableStateOf(false) }
                var showInputDialog by remember { mutableStateOf(false) }
                var inputText by remember { mutableStateOf("") }
                var showProgressDialog by remember { mutableStateOf(false) }
                var progress by remember { mutableFloatStateOf(0.3f) }
                var showFullDialog by remember { mutableStateOf(false) }
                var showDatePickerDialog by remember {mutableStateOf(false)}
                var selectedDate by remember { mutableStateOf(LocalDate.now()) }
                var showTimePickerDialog by remember { mutableStateOf(false) }
                var selectedTime by remember { mutableStateOf(LocalTime.now()) }
                var showSampleDialog by remember { mutableStateOf(false)}
                var showCustomSampleDialog by remember { mutableStateOf(false)}
                var showListDialog by remember { mutableStateOf(false)}
                var showMultiChoiceDialog by remember { mutableStateOf(false)}
                val items = listOf("选项1", "选项2", "选项3", "选项4")
                val selectedOptions = remember { mutableStateListOf<Int>() }
                var showSingleChoiceDialog by remember { mutableStateOf(false) }
                var selectedOption by remember { mutableIntStateOf(0) }
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(6.dp)
                        .verticalScroll(rememberScrollState()),
                    verticalArrangement = Arrangement.spacedBy(6.dp)
                ){

                Button(onClick = { showBottomSheet = true }) {
                    Text("显示底部对话框")
                }
                Button(onClick = { showLoadingDialog = true }) {
                    Text("显示Loading对话框")
                }
                Button(onClick = { showLocationDialog= true }) {
                    Text("显示定位对话框")
                }
                Button(onClick = { showIconDialog= true }) {
                    Text("显示图标样式对话框")
                }
                Button(onClick = { showInputDialog= true }) {
                    Text("显示输入框样式对话框")
                }
                Button(onClick = { showProgressDialog = true }) {
                    Text("显示进度条样式对话框")
                }
                Button(onClick = { showFullDialog = true }) {
                    Text("显示全屏样式对话框")
                }
                Button(onClick = { showDatePickerDialog = true }) {
                    Text("显示日期样式对话框")
                }
                Button(onClick = { showTimePickerDialog = true }) {
                    Text("显示时间选择器对话框")
                }
                Button(onClick = { showSampleDialog = true }) {
                    Text("显示简单的对话框")
                }
                Button(onClick = { showCustomSampleDialog= true }) {
                    Text("显示自定义样式的对话框")
                }
                Button(onClick = { showListDialog = true }) {
                    Text("显示列表样式的对话框")
                }
                Button(onClick = { showMultiChoiceDialog = true }) {
                    Text("显示多选列表样式的对话框")
                }
                Button(onClick = { showSingleChoiceDialog = true }) {
                    Text("显示单选列表样式的对话框")
                }
                Text("输入内容: $inputText")
                Text("单选结果: $selectedOption")
                Text("多选结果: ${selectedOptions.joinToString()}")
                Text("选择日期: $selectedDate")
                Text("选择时间: $selectedTime")

                BottomSheetDialog(showDialog = showBottomSheet, onDismiss = {showBottomSheet = false})

                LoadingDialog(
                    showDialog = showLoadingDialog,
                    onDismissRequest = { showLoadingDialog = false }
                )
                LocationDialog(
                    showDialog = showLocationDialog,
                    onDismiss = { showLocationDialog = false},
                    onConfirm = { showLocationDialog = false}
                )
                IconSimpleDialog(
                    showDialog = showIconDialog,
                    onDismiss = { showIconDialog = false}
                )
                InputDialogExample(
                    showDialog = showInputDialog,
                    onDismiss = {showIconDialog = false},
                    onConfirm = { text ->
                        inputText = text
                        showInputDialog = false
                    }
                )
                LaunchedEffect(showProgressDialog) {
                    if (showProgressDialog) {
                        while (progress < 1f) {
                            delay(100)
                            progress += 0.05f
                        }
                        showProgressDialog = false
                        progress = 0f
                    }
                }
                ProgressDialog(showDialog = showProgressDialog,
                    progress = progress)
                FullScreenDialog(
                    showDialog = showFullDialog,
                    onDismiss = {showFullDialog = false}
                )
                DatePickerDialog(
                    showDialog = showDatePickerDialog,
                    onDismiss = { showDatePickerDialog = false},
                    onDateSelected = { date ->
                        selectedDate = date
                        showDatePickerDialog = false
                    }
                )
                TimePickerDialogSample(
                    showDialog = showTimePickerDialog,
                    onDismiss =  { showTimePickerDialog = false},
                    onTimeSelected = { time ->
                        selectedTime = time
                        showTimePickerDialog = false
                    }
                )
                SampleDialog(
                    showDialog = showSampleDialog,
                    onDismiss = {showSampleDialog = false},
                    onConfirm = {showSampleDialog = false}
                )
                CustomStyledDialog(
                    showDialog = showCustomSampleDialog,
                    onDismiss = {showCustomSampleDialog = false},
                )
                ListSelectionDialog(
                    showDialog = showListDialog,
                    onDismiss = { showListDialog = false },
                    title = "请选择一个选项",
                    items = items,
                    onItemSelected = { index ->
                        println("选择了: ${items[index]}")
                    }
                )
                MultiChoiceDialog(
                    showDialog = showMultiChoiceDialog,
                    onDismiss = {showMultiChoiceDialog = false},
                    onConfirm = { indices ->
                        selectedOptions.clear()
                        selectedOptions.addAll(indices)
                        showMultiChoiceDialog = false
                    }
                )
                SingleChoiceDialog(
                    showDialog = showSingleChoiceDialog,
                    onDismiss = { showSingleChoiceDialog = false },
                    onConfirm = { index ->
                        selectedOption = index
                        showSingleChoiceDialog = false
                    }
                )
                    }
            }
        }
    }
}

30.remember简介:

在Jetpack Compose中,remember是一个关键函数,用于在组件的重组过程中保持状态持久化。

一、核心机制解析

  1. 状态保留原理
    remember { mutableStateOf(X) }组合会:

    • ✅ ‌跨重组缓存值‌:当Composable函数因UI更新被重新调用时,避免状态被重置
    • 🔄 ‌响应式绑定‌:与mutableStateOf配合时,状态变更自动触发重组
    • 🧠 ‌存储位置‌:将状态存储在Composition的隐式参数中(通过CompositionLocal实现)
  2. Dialog控制场景
    如您代码中的showBottomSheet等布尔状态:

    kotlinCopy Codevar showDialog by remember { mutableStateOf(false) } 
    // 展开Dialog时:showDialog = true 触发重组
    

二、关键特性对比

特性 使用remember 直接声明变量
重组后状态保留 ✔️ 保持最后一次值 ❌ 每次重置初始值
触发重组能力 需配合mutableStateOf
内存管理 关联Composition生命周期 函数调用周期

31.总结:

以上就是今天的内容,使用Compose实现各种样式的Dialog,基本上满足大部分样式的需求,但是可能还有些特效的这里就不展示了,比如功能性调节音量、apk升级、文件下载、音乐播放等等。

  • 若在首页调用的时候文本太长显示不完整咋办,哎呦~~这是个好问题,别急,有一个可以设置滚动的属性, .verticalScroll(rememberScrollState())。
  • 若觉得默认的弹框圆角太大了咋办?也可以通过设置圆角改变,shape = RoundedCornerShape(6.dp),
  • 若是不想Dialog主动弹出咋办?哎这里也有方法,if(showDialog){},默认是fasle,只有用户点击的才为true.
  • 若是我想点击取消和确定的时候关闭弹框咋办?调用onDismiss和onConfirm的时候设置showDialog为false,调用onDismiss方法即可.
  • 若是我输入了内容下次进来还想显示上次的内容咋办?这也是一个好问题,remember方法和状态解决,var text by remember { mutableStateOf(“”) } var inputText by remember { mutableStateOf(“”) }
  • 若是我想material3和material同时使用咋办?因为这2个有的依赖会有冲突,所以导入依赖的时候要注意版本,导包的时候注意选择material和material3.
  • 今天的内容看着挺多,其实很简单,Dialog设置文本、圆角、图标、标题、内容、按钮排列方式、按钮点击事件等等.
  • 不一定强求大家使用和学习Compose,因为现在都2025年了,新技术太多了,Flutter,Vue和鸿蒙我都做过几个项目,根据自己的实际情况进行选择和学习,这里不评价他们的好坏.
  • 不积跬步,无以至千里.不积小流,无以成江海.

32.源码地址:

https://gitee.com/jackning_admin/compose-dialog-demo


网站公告

今日签到

点亮在社区的每一天
去签到