개발새발 - IT 기술블로그
article thumbnail

안녕하세요. 이번 포스팅에서는 앱의 테마 설정을 클래스에서 변경하는 방법에 대해 알아보겠습니다.

 

아래 예제는 코틀린으로 작성되었습니다.


 

개요

 

앱 테마를 시스템 테마로 설정하여 사용자의 기기에 동기화 시키는 방법도 있지만, 앱의 설정 페이지에 테마를 변경하는 기능을 추가하여 해당 앱에서 사용하는 테마를 정해 줄수도 있습니다.

 

이번 글에서 이벤트에 따라 테마를 변경하는 방법에 대해 소개드리겠습니다.

 

 


 

본문

 

예제 진행 순서

  1. 메인 레이아웃 구성 (테마 변경 버튼 3개 + 테마 변경을 확인 할 텍스트 뷰 1개)
  2. 뷰의 속성에 적용할 테마 별 옵션 생성
  3. 테마를 변경하는 함수 구현
  4. 각 버튼에 테마 변경 함수를 적용
  5. 결과 확인

 

 

메인 레이아웃 구성

 

버튼은 라이트 모드, 다크 모드, 시스템 모드 총 3가지로 구성되어 있습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@color/theme_layout_color">

    <TextView
        android:id="@+id/themeTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="테마 확인용 텍스트 뷰"
        android:textColor="@color/theme_text_color"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/changeLightModeBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="라이트 모드 변경"
        app:layout_constraintTop_toBottomOf="@+id/themeTextView"
        android:layout_marginTop="30dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"/>

    <Button
        android:id="@+id/changeDarkModeBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="다크 모드 변경"
        app:layout_constraintTop_toBottomOf="@+id/changeLightModeBtn"
        android:layout_marginTop="30dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"/>

    <Button
        android:id="@+id/changeSystemModeBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="시스템 모드 변경"
        app:layout_constraintTop_toBottomOf="@+id/changeDarkModeBtn"
        android:layout_marginTop="30dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

뷰의 속성에 적용할 테마 별 옵션 생성

 

다음은 위 뷰 코드에 적용시킨 컬러 속성을 생성하겠습니다.

 

 

colors.xml 파일 생성

 

1. values 우클릭 > New > Values Resource File

 

 

 

2. Night Mode 속성 적용

 

 

 

3. Night Mode 옵션 선택 후 File namecolors로 생성

 

 

 

4. 각각의 values 파일에 속성 생성

 

colors 파일을 생성하면 하나의 colors 패키지에 두 개의 파일이 들어가 있을것입니다.

 

(night) 라고 적힌 파일이 다크 모드에 적용 될 속성들이고, 적히지 않은 파일이 라이트 모드에 적용 될 속성들입니다.

 

라이트 모드 파일엔 아래와 같이 적고

<color name="theme_layout_color">#FFFFFF</color>
<color name="theme_text_color">#000000</color>

 

다크 모드 파일엔 아래와 같이 적습니다.

<color name="theme_layout_color">#000000</color>
<color name="theme_text_color">#FFFFFF</color>

 

 

테마를 변경하는 함수 구현

 

AppCompatDelegate 함수의 setDefaultNightMode 메서드로 앱의 테마를 설정 할 수 있습니다.

 

private fun changeTheme(mode: Int) {
    AppCompatDelegate.setDefaultNightMode(mode)
}

 

 

각 버튼에 테마 변경 함수를 적용

 

AppCompatDelegate 함수의 Int 타입의 Value로 모드를 선언합니다.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val darkBtn: Button = findViewById(R.id.changeDarkModeBtn)
    val lightBtn: Button = findViewById(R.id.changeLightModeBtn)
    val systemBtn: Button = findViewById(R.id.changeSystemModeBtn)

    darkBtn.setOnClickListener {
        changeTheme(AppCompatDelegate.MODE_NIGHT_YES)
    }

    lightBtn.setOnClickListener {
        changeTheme(AppCompatDelegate.MODE_NIGHT_NO)
    }

    systemBtn.setOnClickListener {
        changeTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
    }
}

 

 

결과 확인

 

처음엔 시스템 테마로 적용된 화면이 출력됩니다.

 

다크 모드 변경 버튼을 누르면 다크 모드가 적용되어 뷰가 갱신됩니다.

 

여기서 텍스트 뷰의 색상이 설정한 컬러 속성으로 적용 된 것을 확인하실 수 있습니다.

 

 

라이트 모드 변경 버튼을 클릭하면 다시 하얀색 배경에 검은색 글씨로 출력됩니다.

 

 

 

결론

이렇게 앱의 테마를 변경하는 방법에 대해 알아보았습니다.

 

만약 앱 설정에 해당 기능을 추가하려고 하신다면 SharedPreference를 사용하거나 Room 혹은 SQLite를 사용하여 해당 설정 값을 저장 시켜놓고 적용하시면 될 것 같습니다.

 

예제 과정은 길었으나 코드 자체는 매우 간단하여 쉽게 적용하실 수 있을 것이라 생각합니다. 

 

감사합니다.

 

 

 

 

소스 코드

https://github.com/tekken5953/ChangeThemeExam

 

GitHub - tekken5953/ChangeThemeExam

Contribute to tekken5953/ChangeThemeExam development by creating an account on GitHub.

github.com