システム テーマの変更に対応する
通常、デバイスにはライト テーマとダーク テーマが含まれ、それぞれがオペレーティング システム レベルで設定できる幅広い外観設定を指します。 アプリはこれらのシステム テーマを尊重し、システム テーマが変更されたときにすぐに対応する必要があります。
システム テーマは、デバイスの構成に応じてさまざまな理由で変更される場合があります。 これには、ユーザーによって明示的に変更されているシステム テーマ、時刻によって変更される、低光量などの環境要因によって変化するシステム テーマが含まれます。
.NET Multi-platform App UI (.NET MAUI) アプリは、AppThemeBinding
マークアップ拡張機能や SetAppThemeColor
拡張メソッドと SetAppTheme<T>
拡張メソッドを使用してリソースを使用することで、システム テーマの変更に対応できます。
Note
.NET MAUI アプリは、iOS 13 以上、Android 10 (API 29) 以降、macOS 10.14 以降、Windows 10 以降でのシステム テーマの変更に対応できます。
次のスクリーンショットは、iOS のライト システム テーマと Android のダーク システム テーマのテーマ付きページを示しています。
テーマ リソースの定義と使用
ライト テーマとダーク テーマのリソースは、AppThemeBinding
マークアップ拡張機能、SetAppThemeColor
拡張メソッドと SetAppTheme<T>
拡張メソッドと共に使用できます。 これらの方法では、現在のシステム テーマの値に基づいてリソースが自動的に適用されます。 さらに、これらのリソースを使用するオブジェクトは、アプリの実行中にシステム テーマが変更された場合に自動的に更新されます。
AppThemeBinding マークアップ拡張
AppThemeBinding
マークアップ拡張機能を使用すると、現在のシステム テーマに基づいて、イメージや色などのリソースを使用できます。
AppThemeBinding
マークアップ拡張機能は、次のプロパティを定義する AppThemeBindingExtension クラスによってサポートされています。
object
型のDefault
は、既定で使用するリソースに設定します。object
型のLight
は、デバイスがライト テーマを使用しているときに使用するリソースに設定します。object
型のDark
は、デバイスがダーク テーマを使用しているときに使用するリソースに設定します。object
型のValue
は、マークアップ拡張機能によって現在使用されているリソースを返します。
Note
XAML パーサーでは、AppThemeBindingExtension クラスを AppThemeBinding
に短縮できます。
Default
プロパティは、AppThemeBindingExtension のコンテンツ プロパティです。 したがって、中かっこで表現された XAML マークアップ拡張機能の場合、それが最初の引数であれば、式の Default=
部分を削除できます。
次の XAML の例では、AppThemeBinding
マークアップ拡張機能を使用する方法が示されています。
<StackLayout>
<Label Text="This text is green in light mode, and red in dark mode."
TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
<Image Source="{AppThemeBinding Light=lightlogo.png, Dark=darklogo.png}" />
</StackLayout>
この例では、デバイスがライト テーマを使用している場合、最初の Label のテキストの色が緑色に設定され、デバイスがダーク テーマを使用している場合は赤色に設定されます。 同様に、Image は現在のシステム テーマに基づいて異なるイメージ ファイルを表示します。
ResourceDictionary で定義されているリソースは、StaticResource
マークアップ拡張機能を使用して AppThemeBinding
で使用できます。
<ContentPage ...>
<ContentPage.Resources>
<!-- Light colors -->
<Color x:Key="LightPrimaryColor">WhiteSmoke</Color>
<Color x:Key="LightSecondaryColor">Black</Color>
<!-- Dark colors -->
<Color x:Key="DarkPrimaryColor">Teal</Color>
<Color x:Key="DarkSecondaryColor">White</Color>
<Style x:Key="ButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}" />
<Setter Property="TextColor"
Value="{AppThemeBinding Light={StaticResource LightSecondaryColor}, Dark={StaticResource DarkSecondaryColor}}" />
</Style>
</ContentPage.Resources>
<Grid BackgroundColor="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}">
<Button Text="MORE INFO"
Style="{StaticResource ButtonStyle}" />
</Grid>
</ContentPage>
この例では、デバイスがライト テーマとダーク テーマのどちらを使用しているかに基づいて、Grid スタイルと Button スタイルの背景色が変わります。
さらに、ResourceDictionary で定義されているリソースは、DynamicResource
マークアップ拡張機能を使用して AppThemeBinding
で使用することもできます。
<ContentPage ...>
<ContentPage.Resources>
<Color x:Key="Primary">DarkGray</Color>
<Color x:Key="Secondary">HotPink</Color>
<Color x:Key="Tertiary">Yellow</Color>
<Style x:Key="labelStyle" TargetType="Label">
<Setter Property="Padding" Value="5"/>
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Primary}}" />
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={DynamicResource Primary}, Dark={DynamicResource Secondary}}" />
</Style>
</ContentPage.Resources>
<Label x:Name="myLabel"
Style="{StaticResource labelStyle}"/>
</ContentPage>
拡張メソッド
.NET MAUI には、VisualElement オブジェクトがシステム テーマの変更に対応できるようにする SetAppThemeColor
拡張メソッドと SetAppTheme<T>
拡張メソッドが含まれています。
SetAppThemeColor
メソッドを使用すると、現在のシステム テーマに基づいてターゲット プロパティに設定される Color オブジェクトを指定できます。
Label label = new Label();
label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);
この例では、デバイスがライト テーマを使用している場合、Label のテキストの色は緑色に設定され、デバイスがダーク テーマを使用している場合は赤色に設定されます。
SetAppTheme<T>
メソッドを使用すると、現在のシステム テーマに基づいてターゲット プロパティに設定される T
型のオブジェクトを指定できます。
Image image = new Image();
image.SetAppTheme<FileImageSource>(Image.SourceProperty, "lightlogo.png", "darklogo.png");
この例では、Image は、デバイスがライト テーマを使用しているときには lightlogo.png
を表示し、デバイスがダーク テーマを使用しているときには darklogo.png
を表示します。
現在のシステム テーマを検出する
現在のシステム テーマは、Application.RequestedTheme
プロパティの値を取得することで検出できます。
AppTheme currentTheme = Application.Current.RequestedTheme;
RequestedTheme
プロパティでは、AppTheme
と呼ばれる列挙型が返されます。 AppTheme
列挙型には、次のメンバーが定義されています。
Unspecified
は、デバイスが未指定のテーマを使用していることを示します。Light
は、デバイスがライト テーマを使用していることを示します。Dark
は、デバイスがダーク テーマを使用していることを示します。
現在のユーザー テーマを設定する
アプリで使用されるテーマは、現在動作しているシステム テーマに関係なく、AppTheme
型の Application.UserAppTheme
プロパティで設定できます。
Application.Current.UserAppTheme = AppTheme.Dark;
この例では、現在動作しているシステム テーマに関係なく、システム ダーク モード用に定義されたテーマを使用するようにアプリが設定されています。
Note
UserAppTheme
プロパティを AppTheme.Unspecified
に設定すると、既定でオペレーティング システム テーマに設定されます。
テーマの変更に対応する
デバイスのシステム テーマは、デバイスの構成に応じて、さまざまな理由で変更される場合があります。 .NET MAUI アプリは、Application.RequestedThemeChanged
イベントを処理することで、システム テーマが変更されたときに通知を受け取ることができます。
Application.Current.RequestedThemeChanged += (s, a) =>
{
// Respond to the theme change
};
RequestedThemeChanged
イベントに付随する AppThemeChangedEventArgs
オブジェクトには、AppTheme
型の RequestedTheme
という名前の単一プロパティがあります。 このプロパティを調べて、要求されたシステム テーマを検出できます。
重要
Android でテーマの変更に対応するには、MainActivity
クラスの Activity
属性に ConfigChanges.UiMode
フラグが含まれている必要があります。 Visual Studio プロジェクト テンプレートで作成された .NET MAUI アプリには、このフラグが自動的に含まれています。
.NET MAUI