次の方法で共有


システム テーマの変更に対応する

サンプルを参照します。 サンプルを参照する

通常、デバイスには明るいテーマと暗いテーマが含まれ、それぞれがオペレーティング システム レベルで設定できる幅広い外観設定を指します。 アプリはこれらのシステム テーマを尊重し、システム テーマが変更されたときにすぐに対応する必要があります。

システム テーマは、デバイスの構成に応じてさまざまな理由で変更される場合があります。 これには、ユーザーによって明示的に変更されているシステム テーマ、時刻によって変更される、低光などの環境要因によって変化するシステム テーマが含まれます。

.NET マルチプラットフォーム アプリ UI (.NET MAUI) アプリは、 AppThemeBinding マークアップ拡張機能を使用してリソースを使用し、 SetAppThemeColor および SetAppTheme<T> 拡張メソッドを使用することで、システム テーマの変更に対応できます。

.NET MAUI アプリは、iOS 13 以上、Android 10 (API 29) 以降、macOS 10.14 以降、Windows 10 以降でのシステム テーマの変更に対応できます。

次のスクリーンショットは、iOS のライト システム テーマと Android のダーク システム テーマのテーマ付きページを示しています。

テーマ付きアプリのメイン ページのスクリーンショット。

テーマ リソースの定義と使用

明るいテーマと濃色テーマのリソースは、 AppThemeBinding マークアップ拡張、および SetAppThemeColor および SetAppTheme<T> 拡張メソッドと共に使用できます。 これらの方法では、現在のシステム テーマの値に基づいてリソースが自動的に適用されます。 さらに、これらのリソースを使用するオブジェクトは、アプリの実行中にシステム テーマが変更された場合に自動的に更新されます。

AppThemeBinding マークアップ拡張機能

AppThemeBinding マークアップ拡張機能を使用すると、現在のシステム テーマに基づいて、イメージや色などのリソースを使用できます。

AppThemeBinding マークアップ拡張は、次のプロパティを定義する AppThemeBindingExtension クラスでサポートされています。

  • Default は、object 型の既定で使用するリソースとして設定されます。
  • Lightデバイスがライトテーマを使用しているときに利用するリソースに設定するobjectの型です。
  • Darkを、デバイスがダークテーマを使用中に使用するリソースとして設定するobject型の#。
  • Valueは、マークアップ拡張機能で現在使用されているリソースを返す object型です。

XAML パーサーを使用すると、AppThemeBindingExtension クラスを AppThemeBindingと省略できます。

Default プロパティは、AppThemeBindingExtensionの content プロパティです。 そのため、中かっこで表現された 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で定義されているリソースは、AppThemeBindingマークアップ拡張機能を使用してStaticResourceで使用できます。

<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で定義されているリソースは、AppThemeBindingマークアップ拡張を使用したDynamicResourceでも使用できます。

<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 には、SetAppThemeColor オブジェクトがシステム テーマの変更に応答できるようにするSetAppTheme<T>およびVisualElement拡張メソッドが含まれています。

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: デバイスがダーク テーマを使用していることを示します。

現在のユーザー テーマを設定する

アプリで使用されるテーマは、現在動作しているシステム テーマに関係なく、Application.UserAppTheme型の AppTheme プロパティを使用して設定できます。

Application.Current.UserAppTheme = AppTheme.Dark;

この例では、現在動作しているシステム テーマに関係なく、システム ダーク モード用に定義されたテーマを使用するようにアプリが設定されています。

UserAppThemeプロパティを既定の運用システム テーマにAppTheme.Unspecifiedに設定します。

テーマの変更に対応する

デバイス上のシステム テーマは、デバイスの構成方法に応じて、さまざまな理由で変更される場合があります。 .NET MAUI アプリは、 Application.RequestedThemeChanged イベントを処理することで、システム テーマが変更されたときに通知を受け取ることができます。

Application.Current.RequestedThemeChanged += (s, a) =>
{
    // Respond to the theme change
};

AppThemeChangedEventArgs イベントに付随する RequestedThemeChanged オブジェクトには、RequestedTheme 型の AppTheme という名前の 1 つのプロパティがあります。 このプロパティを調べて、要求されたシステム テーマを検出できます。

Important

Android でテーマの変更に対応するには、MainActivity クラスで ConfigChanges.UiMode 属性に Activity フラグを含める必要があります。 Visual Studio プロジェクト テンプレートで作成された .NET MAUI アプリには、このフラグが自動的に含まれます。