다크 모드가 반영된 사용자 지정 색상 사용하기 - Jetpack Compose

Shawn Kang·2023년 1월 12일
0

Jetpack Compose

목록 보기
6/6
post-thumbnail

개요

요즘 좀 치는 앱들은 시스템에서 다크 모드로 전환하면 앱 색상도 그에 대응되어 바뀌는 경우가 많다. (사실 많다기보다는 90% 이상이 아닐까 싶다.) Compose도 당연히 이를 지원하는데, 보통은 MaterialTheme.colorScheme.* 코드를 통해 색상을 가져다 쓰는 경우가 많다.

Box(
	modifier = Modifier.background(
    	color = MaterialTheme.colorScheme.primary
    )
) {}

MaterialTheme.colorScheme를 통해 색상을 지정하면, 굳이 코드에 조건문을 달아주지 않아도 실제 앱 UI에서 다크 모드 대응이 알아서 된다. 여기까지는 좋은데, 문제는 Material 3는 지정된 종류의 색상 외에 사용자가 원하는 다른 색상을 추가할 수 없다는 점이다. (이 부분은 Material 3 색상 구성에 대해 자세히 알고 있어야 이해가 된다. 필요한 분들은 Material 3: Color System 링크를 참고하기 바란다.)

아래에서 별도 클래스 선언을 통해, 다크 모드 대응이 가능한 사용자 지정 색상을 구성할 수 있는 방법을 알아보자.


구현

먼저 사용자 지정 색상 클래스를 선언할 파일을 생성한다. 음, 사실은 굳이 생성 안 해도 되고, 앱 패키지 경로 기준 /ui.theme/Color.kt 파일에 작성해주어도 된다. 새 거 쓰던 헌 거 쓰던 이건 사용자 마음.

사용자 지정 색상 선언

private val light_Color1 = Color(0xFF000000)
private val dark_Color1 = Color(0xFF000000)

먼저 클래스 최상단에 사용자 지정 색상을 선언해준다. 여기서 중요한 것은 색상 하나에 대해 라이트 모드에서의 색상, 다크 모드에서의 색상, 총 2가지의 색상을 준비해야 한다는 점이다.

변수의 공개 여부는 사실 크게 중요하지 않다. 코드에서는 private 키워드를 붙여 선언했지만, 실제 개발 때 특정 색상을 다이렉트로 꺼내 쓰고 싶다면 지워주고 공개 변수로 써도 괜찮다.

CustomColor 클래스 선언

class CustomColors {
	companion object {
    	private val isDarkTheme: Boolean
    	@Composable
        get() = isSystemInDarkTheme()
    }
}

다음으로 사용자 지정 색상을 담을 클래스를 선언한다. 이름은 사용자 마음대로 정하면 된다. 그리고 다크 모드 여부를 판별하기 위해, private 변수로 isDarkTheme를 선언해준다. isSystemInDarkTheme()는 시스템의 다크 모드 여부를 반환하는 컴포저블 함수이다.

중요한 점 하나로, 이 색상 클래스는 전역으로 사용할 예정이기 때문에, 반드시 클래스 내에 companion object 블록을 열어 그 안에 모든 색상과 isDarkTheme 변수를 다 몰아 넣어야 한다.

클래스 내에 사용자 지정 색상 추가

private val light_Color1 = Color(0xFF000000)
private val dark_Color1 = Color(0xFF000000)

class CustomColors {
    companion object {
        private val darkTheme: Boolean
            @Composable
            get() = isSystemInDarkTheme()

        val Color1: Color
            @Composable
            get() = if (darkTheme) dark_Color1 else light_Color1
    }
}

완성된 코드다.

처음에 클래스 최상단에 선언해 두었던 Raw한 색상들과 조건문을 통해 다크 모드에 대응해준다. 코드가 너무 쉬워서 추가로 설명할 것도 없다.


결론

사실 이건 뭐 문제나 오류의 해결이라기보다는 꿀팁에 가까운 글이었다. 처음에 MaterialTheme.colorScheme에 직접 색상을 추가해보려다가 실패하고, Getter에 @Composable 어노테이션을 붙일 수 있다는 것도 몰라서 몇 시간 삽질하다 얻은 간단한 해결책이었다.

그리고 추가로 이 글의 내용을 200% 활용하기 위해서는 Material 3 테마를 잘 이해하는 것이 반 필수적이라고 생각한다.

Google이 Jetpack Compose와 Flutter 양쪽에서 Material 3를 활용한 버튼, 박스, 카드, 텍스트 필드 등 다양한 UI 요소를 사용하기 편하도록 소스 코드로 구현해두었기 때문에, Material 3를 잘 이해하고 활용할 경우 학교 과제나 사이드 프로젝트 정도는 높은 완성도로 잘 끝낼 수 있을 거라고 생각한다.

아래의 두 링크를 잘 참고하기 바란다.

profile
i meant to be

0개의 댓글