🕶️

既存アプリにダークモードを適用する際に詰まったこと

に公開

はじめに

MaterialAppthemedarkTheme を設定すればOK!...と思いきや、なぜか端末がダークモードでもアプリ内ではずっとライトモードのままという現象。

この記事では、意外と見落としがちなネイティブ(iOS/Android)側の設定という原因と、その解決策を解説します。

問題の状況

MaterialApp.routerthemedarkTheme を提供し、themeMode はデフォルト値(ThemeMode.system)に依存していました。

端末設定をダークモードにしてアプリを起動し、スプラッシュ画面でOSの明るさ情報を確認したところ:

final themeBrightness = Theme.of(context).brightness;
final osBrightness = MediaQuery.platformBrightnessOf(context); 

print('Theme Brightness: $themeBrightness'); 
print('OS Brightness: $osBrightness');

期待する結果は両方とも Brightness.dark でしたが、実際は:

flutter: Theme Brightness: Brightness.light
flutter: OS Brightness: Brightness.light

原因の特定

MediaQuery.platformBrightnessOf(context) は、OSが現在どのテーマを適用しているかという「生の情報」をFlutterに伝えます。この「生の値」までもが Brightness.light となっていることから、問題はFlutterの設定よりも前のレイヤー(ネイティブコード)にあると特定できました。

結論:アプリのネイティブ設定で、テーマの自動切り替えがブロックされ、「ライトモード」に固定されていたことが原因でした。

解決策

iOS の設定解除

ios/Runner/Info.plist を開き、以下のキーを探します:

<key>UIUserInterfaceStyle</key>
<string>Light</string>

このキーが <string>Light</string> となっている場合、アプリはOSの設定を無視し、常にライトモードで動作します。

解決策:この <key>...</string> のブロックを Info.plist から完全に削除するか、値を <string>Automatic</string> に変更します。

(削除することで、OSの設定にテーマの決定を委ねるのが最もクリーンな方法です。)

Android の設定確認

android/app/src/main/res/values/styles.xml を開き、アプリの基本テーマの parent 属性を確認します:

<style name="LaunchTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> 
</style>

もし Theme.AppCompat.Light のようなライト専用のテーマを参照していたら、DayNight が含まれるテーマ(例: Theme.MaterialComponents.DayNightTheme.AppCompat.DayNight)に変更してください。

まとめ

この問題は、Flutterのコードが正しくても、ネイティブ設定が原因でOSの情報が遮断されていたという典型的な落とし穴でした。

これらの設定を修正した後、必ず以下の手順を実行してください:

  1. ターミナルで flutter clean を実行
  2. アプリを完全に停止し、再ビルド(Run)します

これで、Flutterアプリはユーザーの端末設定に正しく追従し、美しいダークモードが表示されるはずです!

Discussion