Image
Android Jetpack Compose UI/Compose Dialog

[Android Dialog] 1. Compose Dialog를 이용해 커스텀 다이얼로그 만들기

Compose에서 사용할 수 있는 다이얼로그의 종류

Compose에서는 두가지 종류의 Dialog를 사용할 수 있다.

  • Dialog : 커스텀한 다이얼로그를 생성
  • AlertDialog : 미리 정의된 스타일에 따라 Dialog를 생성

Dialog를 이용하면 커스텀한 다이얼로그를 생성할 수 있으며, AlertDialog 함수는 정해진 스타일에 따라 Dialog를 생성한다. 둘 모두 장단점이 있다.

 

  • Dialog를 사용하면 다이얼로그를 만드는데 시간이 오래 걸리지만 필요한 디자인을 충분히 적용할 수 있다. 
  • AlertDialog를 사용하면 미리 정의되어 있는 스타일을 사용할 수 있어 다이얼로그를 만드는데 시간이 적게 걸리고 코드를 직관적으로 만들 수 있지만 정해진 스타일대로만 정의가 가능하다.

 

AlertDialog도 내부에서는 Dialog를 규격화해 사용하므로 이번 글에서는 먼저 Dialog를 이용한 커스텀 다이얼로그를 만드는 방법에 대해 알아볼 것이다.

 

Dialog를 이용한 커스텀 다이얼로그 만들기

커스텀 다이얼로그를 만들기 위한 Dialog 컴포저블은 다음 3개의 파라미터를 받는다. 

@Composable
fun Dialog(
    onDismissRequest: () -> Unit,
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit
)

이 3개의 파라미터는 다음의 역할을 한다.

  • onDismissRequest : 다이얼로그 종료 요청이 왔을 때의 처리
  • properties : 다이얼로그 속성(다이얼로그 종료 규칙, 보안 규칙, 너비 규칙)을 정의
  • content : 다이얼로그의 UI를 정의

 

이 글에서는 커스텀 다이얼로그를 만들기 위해 content에 대해 다룬다.

 

다이얼로그의 UI를 정의하는 content

content에서는 다이얼로그의 UI를 정의한다. 다른 Composable들과 똑같이 정의한다.

 

예를 들어 우리가 다음과 같은 Dialog를 만들고 싶다고 하자.

그림1. Dialog

Dialog 안쪽의 Content는 다음과 같이 이루어진다.

1. Column Layout 속의 자식 컴포저블은 5가지이다.

2. Spacer을 통해 여유 공간을 주고

3. "Kotlin World" Text를 만들고

4. Spacer로 다시 여유 공간을 주고

5. "Enter" 버튼을 만들고

6. Spacer로 여유 공간을 준다.

 

이를 표현한 DialogContent 컴포저블의 코드는 다음과 같다.

@Composable
fun DialogContent(){
    Column {
        Spacer(
            modifier = Modifier
                .height(12.dp)
                .fillMaxWidth()
        )
        Text(
            "Kotlin World",
            textAlign = TextAlign.Center,
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentSize()
                .padding(vertical = 8.dp),
            fontSize = 16.sp,
            lineHeight = 17.sp
        )
        Spacer(
            modifier = Modifier
                .height(12.dp)
                .fillMaxWidth()
        )
        Button(
            onClick = {}, modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 20.dp), shape = RoundedCornerShape(24.dp)
        ) {
            Text("Enter", fontSize = 16.sp)
        }
        Spacer(
            modifier = Modifier
                .height(12.dp)
                .fillMaxWidth()
        )
    }
}

 

우리는 단순히 이를 다이얼로그의 안쪽에 넣음으로써 다이얼로그를 만들 수 있다.

@Composable
fun KotlinWorldDialog() {
    Dialog(onDismissRequest = {}) {
        DialogContent()
    }
}

하지만 위 코드를 실행하면 문제가 생기게 된다. 바로 우리가 예상한것과 달리 다음과 같이 배경색이 투명한 검은색으로 나오기 때문이다.

그림2. Surface가 없는 content

이유는 Dialog는 기본적으로 별도의 Surface에 그려지는데 해당 Surface의 배경색이 투명한 검은색으로 설정되어 있기 때문이다. 따라서 Dialog Content를 위한 별도의 Surface를 설정하지 않으면 그림2와 같이 부모 Surface를 따라가 투명한 검은색으로 보이게 된다.

 

다이얼로그에 배경색을 정의하려면 Dialog Content를 위한 별도의 Surface를 정의해줘야 한다.

그림3. Dialog의 Surface와 Dialog Content의 Surface

 

위 Surface를 정의한 최종 코드는 다음과 같다. Dialog 내부에 Surface를 정의해주고 그 안에서 Dialog의 Content를 그리는 식으로 한다. Surface의 Shape은 RoundedCornerShape으로 해서 둥근 모서리를 만들고 색은 하얀색으로 만든다. 그러면 그림3의 다이얼로그가 출력된다.

@Preview
@Composable
fun KotlinWorldDialog() {
    Dialog(onDismissRequest = {}) {
        Surface(
            modifier = Modifier
                .width(200.dp)
                .wrapContentHeight(),
            shape = RoundedCornerShape(12.dp),
            color = Color.White
        ) {
            DialogContent()
        }
    }
}

 

반응형

 

이 글의 저작권은 '조세영의 Kotlin World' 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com