LoginSignup
0
1

More than 1 year has passed since last update.

今更ながらダークテーマ対応

Last updated at Posted at 2021-08-09

最近になってようやくダークテーマ関連に足を踏み入れたのでまとめてみようと思いました。

呼び方

・私も勘違いしていたのですが、Androidはダークモード・ライトモードではなくダークテーマ・ライトテーマと呼ぶそうですね。
参考:ダークテーマ

色分け

・ライトテーマ(デフォルト)は今まで通りvalues/colors.xmlに定義しておくとして、ダークテーマ用のものはどうすれば良いのでしょうか。答えは簡単で、values-night/colors.xmlを作成、その中に定義しておけばよさそうです。
ただし、ライトテーマ用のcolors.xmlに定義がないものをダークテーマ用のcolors.xmlに定義することはできないようです。あくまでオーバーライドです。

基準色

・themeとして設定。以下あたりでしょうか。

Theme.AppCompat
Theme.AppCompat.DayNight
Theme.MaterialComponents.DayNight

任意のタイミングでテーマを切り替える

・最近はアプリ毎にテーマを設定できることがありますね。そのような場合はアプリ内設定画面などに適当なラジオボタンなどを置いてユーザの入力を読み取り、変更&保持を行えばよさそうです。
保持しているものを該当ActivityのonCreateで実行すると再度onCreateが走ってしまうので、もっと前段でテーマは決めてしまうのがよいですね。
(また、各Activityで受け取ることもできるようです。参考:ダークテーマ 構成の変更
切り替えなどを行うUtilクラスがあると便利そうですね。ざっくりサンプルですが。

SampleThemeManager.kt
object SampleThemeManager {

    /**
     * テーマを変更する(アプリ全体に反映).
     * @param mode MODE_NIGHT_YES, MODE_NIGHT_NO, MODE_NIGHT_FOLLOW_SYSTEM
     */
    fun changeTheme(mode: Int) {
        // OS10以上の時だけ実行する
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            return
        }

        // modeが妥当かのチェック処理

        // 実際に変更する
        AppCompatDelegate.setDefaultNightMode(mode)

        // 設定された値を保持する処理
    }

    /**
     * テーマを変更する(Activity単位で反映).
     * @param appCompatDelegate activityのdelegateなど
     * @param mode MODE_NIGHT_YES, MODE_NIGHT_NO, MODE_NIGHT_FOLLOW_SYSTEM
     */
    fun changeTheme(appCompatDelegate: AppCompatDelegate, mode: Int) {
        // OS10以上の時だけ実行する
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            return
        }

        // modeが妥当かのチェック処理

        // 実際に変更する
        appCompatDelegate.localNightMode = mode

        // 設定された値を保持する処理
    }

    /**
     * ダークテーマかどうか.
     * @param activity チェック対象
     * @return trueならばダークテーマ
     */
    fun isDarkTheme(activity: Activity): Boolean {
        return activity.resources.configuration.uiMode and
                Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
    }
}

上記にあるように、適用範囲によって使い分ける必要があります。

アプリケーション全体に適用する Activityにだけ適用する
AppCompatDelegate.setDefaultNightMode() appCompatDelegate.localNightMode

最後に

ダークテーマはもはや無ければならないものになっているので、今後も知見を広げていきたいと思います。
リリース後の機能追加等でダークテーマを実装する場合はリソースの整理が大変になるので、できれば最初から要件には入れていきたいです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1