[안드로이드 스튜디오 코틀린] Compose로 아이폰 Dialog 같은 Custom Dialog 만들기
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