모달창을 만들어보자

milkbottle·2024년 5월 26일
0

모달창

아래의 사진을 모달창이라고 부른다.

주변에 회색배경이 깔리고 그 위에 이미지가 있는..

보통 Dialog 아니면 Modal 이라고 많이 칭한다.

이를 Jetpack Compose로 구현하려면 어떻게 해야할까?

로직

먼저 사용자가 어떤 행동을 취할 수 있을지 알아보자.

  1. 사용자는 모달창을 연다.
  2. 사용자는 모달창을 닫는다.

의 2가지 행동이 있을 것이다.

다음의 모달창이 있다고 하자.

여기서 사용자가 모달창을 닫는법은 무엇일까?

  1. 우측 상단의 X 아이콘을 눌러 닫는다.

이게 다일까? 사용자의 경험에 따르면 외부 검은 투명 배경을 눌러도 닫히도록 해야한다.

즉, 사용자가 할 수 있는 행동은 3가지이다.

  1. 사용자는 모달창을 연다.
  2. 사용자는 우측 상단의 X 아이콘을 눌러 닫는다.
  3. 사용자는 검은 투명 배경을 눌러 닫는다.

구현

투명 배경

먼저 검은 투명을 구현해야한다. Jetpack Compose에선 Colorcopy()기능을 통해 alpha값을 조절할 수 있다.

Surface(
	modifier = Modifier.fillMaxSize(),
    color =  Color(0Xff000000).copy(alpha = 0.5f)
)

사실 0xff 부분의 ff가 alpha에 대한 값이라 이것을 조절해도 상관없지만, 보통 투명도는 0~100%의 값으로 조절하기에 이 방법이 편할 것이다.

가운데 정렬

Surface(
	modifier = Modifier.fillMaxSize(),
    color =  Color(0Xff000000).copy(alpha = 0.5f)
) {
	Box(
    	contentAlignment = Alignment.Center
    ) {
    	모달()
    }
}

위와 같은 방법으로 진행하였다.

모달창

Surface(
	modifier = Modifier.fillMaxSize(),
    color =  Color(0Xff000000).copy(alpha = 0.5f)
) {
	Box(
    	contentAlignment = Alignment.Center
    ) {
    	CustomModal()
    }
}

@Composable
fun CustomModal() {
	Surface(
    	color = 원하는 컬러,
        shape = RoundedCornerShape(10.dp) // 원하는 만큼 라운드코너
    ) {
    	Column(
        	modifier = Modifier.padding(20.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
        	Image(
                modifier = Modifier
                    .size(24.dp)
                    .align(Alignment.End)
                    .clickable { 창닫기() },
                painter = painterResource(id = R.drawable.cancel),
                contentDescription = "modal_close",
            )
            Spacer(modifier = Modifier.height(12.dp))
            나머지 모달의 디자인들 ....
        }
    }
}

CustomModal을 살펴보면, Image로 X 아이콘에 해당하는 cancel 이미지를 불러와 clickable 을 주었다.

필자는 Button으로 클릭기능을 하지않고, clickable 로 클릭기능을 넣는 것을 선호한다.

하지만, 아까 언급한 검은 투명 배경 영역에 대한 클릭효과는 넣지 않았다.

투명 배경 클릭효과

Surface(
	modifier = Modifier.fillMaxSize().clickable{ 창닫기() },
    color =  Color(0Xff000000).copy(alpha = 0.5f)
)

이렇게 단순히 clickable{ 창닫기() } 를 주면 될까?

사실 clickable이든, Button이든 클릭효과를 주게 되면 물방울 처럼 퍼지는 ripple 효과가 발생한다.

이는 사용자가 클릭을 했다는 것을 인지시키기위해 안드로이드에서 넣은 애니메이션이다.

X 아이콘을 눌러 닫을 때는 ripple 효과가 문제없지만, 투명 배경을 클릭할 때 배경이 ripple 효과가 있는 것은 어색하다.

그래서 이 효과를 지워야한다.

ripple 효과 제거


                Surface(
                    modifier = Modifier
                        .fillMaxSize()
                        .clickable(
                            indication = null,
                            interactionSource = remember { MutableInteractionSource() }) {
                            창닫기()
                        },
                    color = Color.Black.copy(alpha = 0.5f),
                ) 

이렇게 indication, interactionSource를 통해 ripple 효과를 제거할 수 있다.

정리

  • Modal = Dialog

  • Ripple 효과: 클릭할 때 물방울처럼 퍼지는 애니메이션
    indication, interactionSource로 제거가능

0개의 댓글