안드로이드 스튜디오

[안드로이드 스튜디오 코틀린] Compose로 아이폰 Dialog 같은 Custom Dialog 만들기

권송미 2024. 6. 11. 13:41
728x90
반응형

 

 

 

 

 

 

Compose로 아이폰 느낌의 Custom Dialog 를 만들어봅시다

 

 

 

네이버 캘린더 아이폰 기본 다이얼로그

 

 

 

이런 느낌의 Dialog를 Compose로 구현해보겠습니다.

 

 

 

 

 

 

 

 

 

 

프로젝트를 생성하고 utils라는 Package를 만들어줍니다.

 

 

 

 

 

 

 

 

그 다음 생성한 패키지에

 

 

 

위에 처럼 Kotlin CustomDialog.kt 파일을 만들어줍니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그리고 미리 볼 수 있는 Preview를 만들어서

 

 

 

 

 

 

 

위처럼 기본 함수 Setting을 합니다.

 

 

 

 

 

 

 

 

AlertDialog를 사용할 까 그냥 Dialog를 사용할 까 고민을 했습니다 흠..

 

 

 

 

 

 

 

 

AlertDialog는

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AlertDialogExample(
    onDismissRequest: () -> Unit,
    onConfirmation: () -> Unit,
    dialogTitle: String,
    dialogText: String,
    icon: ImageVector,
) {
    AlertDialog(
        icon = {
            Icon(icon, contentDescription = "Example Icon")
        },
        title = {
            Text(text = dialogTitle)
        },
        text = {
            Text(text = dialogText)
        },
        onDismissRequest = {
            onDismissRequest()
        },
        confirmButton = {
            TextButton(
                onClick = {
                    onConfirmation()
                }
            ) {
                Text("Confirm")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    onDismissRequest()
                }
            ) {
                Text("Dismiss")
            }
        }
    )
}

 

 

이렇게 전형적인 Dialog로, 내가 Body에 담을 내용을 커스텀 할 수가 없었습니다.

 

 

 

 

 

 

 

 

 

 

 

그래서 

 

 

 

Dialog를 사용해서 조금 더 커스텀 하게 사용하기로 했습니다.

 

- 구글 예시

@Composable
fun DialogWithImage(
    onDismissRequest: () -> Unit,
    onConfirmation: () -> Unit,
    painter: Painter,
    imageDescription: String,
) {
    Dialog(onDismissRequest = { onDismissRequest() }) {
        // Draw a rectangle shape with rounded corners inside the dialog
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .height(375.dp)
                .padding(16.dp),
            shape = RoundedCornerShape(16.dp),
        ) {
            Column(
                modifier = Modifier
                    .fillMaxSize(),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Image(
                    painter = painter,
                    contentDescription = imageDescription,
                    contentScale = ContentScale.Fit,
                    modifier = Modifier
                        .height(160.dp)
                )
                Text(
                    text = "This is a dialog with buttons and an image.",
                    modifier = Modifier.padding(16.dp),
                )
                Row(
                    modifier = Modifier
                        .fillMaxWidth(),
                    horizontalArrangement = Arrangement.Center,
                ) {
                    TextButton(
                        onClick = { onDismissRequest() },
                        modifier = Modifier.padding(8.dp),
                    ) {
                        Text("Dismiss")
                    }
                    TextButton(
                        onClick = { onConfirmation() },
                        modifier = Modifier.padding(8.dp),
                    ) {
                        Text("Confirm")
                    }
                }
            }
        }
    }
}

 

 

 

 

 

 

 

 

 

맨 처음은 취소, 확인, title, content를 아래처럼 해줍니다.

 

@Composable
fun CustomDialog(
    onDismissRequest: () -> Unit,
    dismissText: String,
    onConfirmation: () -> Unit,
    confirmText: String,
    title: String,
    content: @Composable () -> Unit
) {
    Dialog(
        onDismissRequest = { /*TODO*/ }
    ) {

    }

}

@Preview
@Composable
fun CustomDialogPreview() {
    CustomDialog(
        onDismissRequest = {},
        dismissText = "취소",
        onConfirmation = {},
        confirmText = "확인",
        title = "타이틀입니다"
    ) {
        //Text("내용입니다")
    }
}

 

 

content를 저렇게 해주는 이유는 Composable을 인자로 받아서 다이얼로그 내부의 콘텐츠를 유연하게 정의할 수 있게 해주기 때문입니다.

 

 

 

 

 

 

 

이제

CustomDialog 함수의 View를 만들어주면

 

 

@Composable
fun CustomDialog(
    onDismissRequest: () -> Unit,
    dismissText: String,
    onConfirmation: () -> Unit,
    confirmText: String,
    title: String,
    content: @Composable () -> Unit
) {
    Dialog(
        onDismissRequest = onDismissRequest,
        content = {
            Surface(
                color = Color.White,
                shape = RoundedCornerShape(10.dp),
                modifier = Modifier.width(270.dp)
            ) {
                Column(
                    modifier = Modifier.padding(top = 16.dp)
                ) {
                    Text(
                        text = title,
                        fontWeight = FontWeight.ExtraBold,
                        color = Color.Black,
                        fontSize = 17.sp,
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(bottom = 20.dp),
                        textAlign = TextAlign.Center
                    )

                    // Composable 함수를 사용해서 나중에 Body를 정의할 부분
                    content()

                    Divider(
                        modifier = Modifier
                            .height(0.3.dp)
                            .background(Color.Gray)
                    )

                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(44.dp),
                        horizontalArrangement = Arrangement.Center
                    ) {
                        TextButton(
                            onClick = onDismissRequest,
                            modifier = Modifier.weight(1f)
                        ) {
                            Text(
                                text = dismissText,
                                color = Color.Blue,
                                fontSize = 15.sp
                            )
                        }

                        Divider(
                            modifier = Modifier
                                .width(0.33.dp)
                                .fillMaxHeight()
                                .background(Color.Gray)
                        )

                        TextButton(
                            onClick = onConfirmation,
                            modifier = Modifier.weight(1f)
                        ) {
                            Text(
                                text = confirmText,
                                color = Color.Blue,
                                fontWeight = FontWeight.Bold,
                                fontSize = 15.sp
                            )
                        }
                    }
                }
            }
        }
    )
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이렇게 Preview가 보이는걸 알 수 있습니다.

 

 

 

 

 

 

 

 

그리고 또 Body를 채우면

 

 

 

@Preview
@Composable
fun CustomDialogPreview() {
    CustomDialog(
        onDismissRequest = {},
        dismissText = "취소",
        onConfirmation = {},
        confirmText = "확인",
        title = "타이틀입니다"
    ) {
        Text(
            text = "내용입니다, 내용입니다, 내용입니다, 내용입니다내용입니다내용입니다내용입니다",
            textAlign = TextAlign.Center,
            modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp, start = 10.dp, end = 10.dp)
        )
    }
}

 

 

 

 

 

 

 

 

 

 

이렇게 잘 나오는 것을 볼 수 있습니다 !

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고

https://developer.android.com/develop/ui/compose/components/dialog?hl=ko

 

대화상자  |  Jetpack Compose  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 대화상자 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Dialog 구성요소는 기본 앱 콘텐츠 위의 레이

developer.android.com

 

728x90
반응형