maui-theming について
.NET MAUIアプリのテーマ設定を案内し、OS連動のライト・ダークモードとカスタムテーマの実行時切り替えを説明します。アプリ開発者向けに、方式の選択とプラットフォーム固有の注意点をまとめています。
主な機能
- 01AppThemeBindingによるOS連動の明暗モード
- 02ResourceDictionaryを使ったカスタムテーマ
- 03システムテーマと独自テーマの併用
- 04実行時切り替えに使うDynamicResource
- 05AndroidのUiMode設定に関する注意
活用シーン
- 01ライト・ダークモードの自動適用
- 02ブランドテーマの実行時切り替え
- 03Androidのテーマ変更時のアクティビティ再起動を防止
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-themingインストール後、Claude Code で/maui-themingを入力して読み込まれたか確認します。
同梱ファイルreferences/theming-api.md
詳細
.NET MAUI のテーマ設定
アプローチの選択
| アプローチ | 最適な用途 | 制限事項 |
|---|---|---|
| AppThemeBinding | OS に合わせたライト/ダークの自動切り替え — コードを最小限に抑えられます | テーマは 2 種類(ライト+ダーク)のみです |
| ResourceDictionary swap | ブランドに合わせたカスタムテーマ、2 種類を超えるテーマ、ユーザー設定 | 設定が増え、すべての箇所で DynamicResource を使用する必要があります |
| 両方を組み合わせる | OS への自動対応+カスタムテーマカラー | 最も柔軟ですが、最も複雑です |
特に注意すべき点
Android:ConfigChanges.UiMode は必須です
MainActivity には ConfigChanges.UiMode を必ず含めてください。含めないと、テーマ変更イベントが
発生せず、変更に対応する代わりにアクティビティが再起動します。
[Activity(Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize
| ConfigChanges.Orientation
| ConfigChanges.UiMode // ← Required for theme detection
| ConfigChanges.ScreenLayout
| ConfigChanges.SmallestScreenSize
| ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity { }
UiMode がない場合、Android の設定でダークモードを切り替えるとアクティビティが完全に
再起動され、ナビゲーション状態が失われ、ユーザーにはクラッシュしたように見えます。
CSS テーマは実行時に切り替えられません
MAUI は CSS によるスタイル設定をサポートしていますが、CSS ベースのテーマは実行時に 動的に切り替えられません。実行時の切り替えには ResourceDictionary によるテーマ設定を使用してください。
DynamicResource と StaticResource
ResourceDictionary でテーマを切り替える場合は、必ず DynamicResource を使用してください。
<Label TextColor="{DynamicResource PrimaryTextColor}" />
<Label TextColor="{StaticResource PrimaryTextColor}" />
クイックリファレンス
- OS のライト/ダークテーマ →
AppThemeBindingマークアップ拡張 - C# のテーマカラー →
SetAppThemeColor()、SetAppTheme<T>() - OS のテーマを読み取る →
Application.Current.RequestedTheme - テーマを強制する →
Application.Current.UserAppTheme = AppTheme.Dark - テーマ変更 →
RequestedThemeChangedイベント - カスタム切り替え →
MergedDictionariesのResourceDictionaryを入れ替える - 実行時のバインディング →
DynamicResource(StaticResourceではありません)
コメント
Markdown 対応