ラベル ダークモード の投稿を表示しています。 すべての投稿を表示
ラベル ダークモード の投稿を表示しています。 すべての投稿を表示

2023年7月11日火曜日

Android ダークモードを実装するときの実装手順について解説

どうも。どっことです。今回はダークモード対応に関する実装について解説します。

ダークモードを実装する

アプリをいい感じに見せたいのであれば、ダークモード対応は今や必須の項目の一つではないでしょうか。ユーザへの見せ方をライト/ダークでそれぞれ管理する必要があるのは大変ですが、それ以上にユーザに好印象を与えることができるアプローチになります。今回はそんなダークモード対応をする時のアプローチ方法を解説します。

実装手順

必要最小限でダークモードを対応する場合、以下の手順になります。

  • ダークモードにした時にどのように見えるか確認
  • 修正が必要な箇所について色指定を修正
  • ライト/ダークモードの切り替え動線を用意

順番に解説していきます。

ダークモードにした時にどのように見えるか確認

まずは以下をApplication#onCreate()で呼び出してみましょう。

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

これを呼び出すとアプリがダークモードで表示されます。この状態でアプリがどのように見えるか確認しましょう。

修正が必要な箇所について色指定を修正

テキストが背景と同色で見えなくなっているなど、残念な表示となっている箇所は適宜修正しましょう。values-nightフォルダを作ってそこにcolors.xmlを用意し、色指定を追加してください。このときvalues/colors.xmlでの定義とvalues-night/colors.xmlで定義するnameは同じものを指定してください。そうすれば、ライト/ダークの切り替え時にそれぞれの色指定を参照してくれます。逆に異なるものを指定すると、ビルド時に警告表示されるはずです。

ライト/ダークモードの切り替え導線を用意

あとはユーザがライト/ダークモード(+端末の設定に従う設定)を切り替えられるよう、切り替えスイッチのような動線を用意しておきましょう。アプリ内に設定画面などがあれば、そちらに用意するのが適切かと思います。

切り替え時の処理

ユーザがスイッチなどで設定を変えた場合の処理が必要です。ユーザの切り替え設定に従い、テーマを更新します。また、設定した値はアプリ固有領域(例えばSharedPreferenceなど)に保持しておきましょう。以下はSharedPreferenceに保存した時のサンプルです。

/** 
 * ユーザが設定したテーマ。
 * AppCompatDelegate.MODE_NIGHT_YES, 
 * AppCompatDelegate.MODE_NIGHT_NO など 
 **/
val value = AppCompatDelegate.MODE_NIGHT_YES
AppCompatDelegate.setDefaultNightMode(value)
getSharedPreferences("sample",  MODE_PRIVATE)
  .edit().putInt("theme_setting", value).apply()

アプリ起動時の処理

アプリを起動した時に、ユーザの設定に合わせてテーマを更新する必要があります。先ほど実装したApplication#onCreate()の実装を以下に変更してください。

val value = getSharedPreferences("sample", MODE_PRIVATE)
            .getInt("theme_setting", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
AppCompatDelegate.setDefaultNightMode(value)

まとめ

今回は、アプリにダークモードを実装する時の実装手順について解説しました。ダークモードはユーザに良い印象を提供するためには必須の項目となっているので、今回の内容を参考にして是非対応してみてください。

参考

2021年4月19日月曜日

Android カスタムViewでもダークモード対応する

経緯

カスタムViewを作ったけど、ダークモードのことをまったく気にしなかったせいで、カスタムViewの背景が真っ白になってしまった。

思い

values-nightフォルダを用意してcolors.xmlを入れるのもいいけど、そこまでしなくても標準の設定で十分なんだよなぁ。じゃあ標準ってどうやればいいんだ?と思って開発者サイト見たら、しっかり書いてあった。

ダークテーマ

ハードコードした色を削除してください(白を指定した背景色など)。その代わりとして ?android:attr/colorBackground テーマ属性を使用します。

なーんだ。これ使えば楽勝じゃん。

残念。mergeタグにbackgroundは効かないんだな。

mergeタグってこういう所で融通きかないよね。duplicateParentStateつけないと正しく動作しない問題は解決してくれるけど。さて、となると?android:attr/colorBackgroundをコード上で参照しないといけないけど、どう実装すればいいんだ?

答え

ググったらバリバリ答えが書いてあるページが出てきた。

how to get background color from current theme programmatically

TypedValueを使えば参照できるらしい。というわけで最終的に実装した形がこれ

typedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true)
setBackgroundColor(typedValue.data)

全然ちょろかった。

移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。