アプリケーションのシステム テーマの変更に Xamarin.Forms 対応する

サンプルのダウンロードサンプルのダウンロード

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

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

Xamarin.Formsアプリケーションは、マークアップ拡張機能と 拡張SetOnAppTheme<T>メソッドと 拡張メソッドを使用してリソースをAppThemeBinding使用することで、システム テーマの変更にSetAppThemeColor対応できます。

システム テーマの変更に対応するには、次の Xamarin.Forms 要件を満たす必要があります。

  • Xamarin.Forms 4.6.0.967 以上。
  • iOS 13 以降。
  • Android 10 (API 29) 以上。
  • UWP ビルド 14393 以降。
  • macOS 10.14 以降。

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

アプリのメイン ページのスクリーンショット。テーマ付きiOS と Android のメイン ページ付きアプリの詳細ページ、テーマ付きアプリの iOS と Androidスクリーンショット

テーマ リソースを定義して使用する

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

AppThemeBinding マークアップ拡張

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

<ContentPage ...>
    <StackLayout Margin="20">
        <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>
</ContentPage>

この例では、デバイスがライト テーマを使用している場合は、最初 Label ののテキストの色が緑色に設定され、デバイスがダーク テーマを使用している場合は赤に設定されます。 同様に、 には Image 、現在のシステム テーマに基づいて異なるイメージ ファイルが表示されます。

さらに、 で ResourceDictionary 定義されているリソースは、マークアップ拡張機能と共に 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 、デバイスがライト テーマとダーク テーマのどちらを使用しているかに基づいて変わります。

マークアップ拡張機能の AppThemeBinding 詳細については、「 AppThemeBinding マークアップ拡張機能」を参照してください。

拡張メソッド

Xamarin.Formsには、SetOnAppTheme<T>オブジェクトがシステム テーマの変更に応答できるようにする VisualElement および 拡張メソッドが含まれていますSetAppThemeColor

SetAppThemeColorメソッドを使用すると、Color現在のシステム テーマに基づいてターゲット プロパティに設定されるオブジェクトを指定できます。

Label label = new Label();
label.SetAppThemeColor(Label.TextColorProperty, Color.Green, Color.Red);

この例では、 のテキストの Label 色は、デバイスがライト テーマを使用している場合は緑色に設定され、デバイスがダーク テーマを使用している場合は赤に設定されます。

SetOnAppTheme<T>メソッドを使用すると、現在のシステム テーマに基づいてターゲット プロパティに設定される型Tのオブジェクトを指定できます。

Image image = new Image();
image.SetOnAppTheme<FileImageSource>(Image.SourceProperty, "lightlogo.png", "darklogo.png");

この例では、 は、Imageデバイスがライト テーマを使用している場合とdarklogo.png、デバイスがダーク テーマを使用している場合に表示されますlightlogo.png

現在のシステム テーマを検出する

現在のシステム テーマは、 プロパティの Application.RequestedTheme 値を取得することで検出できます。

OSAppTheme currentTheme = Application.Current.RequestedTheme;

プロパティは RequestedTheme 列挙メンバーを OSAppTheme 返します。 OSAppTheme 列挙体を使って、次のメンバーを定義できます。

  • Unspecified。これは、デバイスが未指定のテーマを使用していることを示します。
  • Light。これは、デバイスがライト テーマを使用していることを示します。
  • Dark。これは、デバイスがダーク テーマを使用していることを示します。

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

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

Application.Current.UserAppTheme = OSAppTheme.Dark;

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

注意

プロパティOSAppTheme.UnspecifiedUserAppTheme に設定して、既定の操作システム テーマに設定します。

テーマの変更にReactする

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

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

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

重要

Android のテーマの変更に対応するには、クラスの ConfigChanges.UiMode 属性MainActivityに フラグをActivity含める必要があります。