アプリケーションのテーマを Xamarin.Forms 適用する

サンプルのダウンロード サンプルをダウンロードする

Xamarin.Forms アプリケーションは、マークアップ拡張機能を使用して、実行時に動的にスタイル変更に応答でき DynamicResource ます。 このマークアップ拡張機能は、 StaticResource マークアップ拡張機能に似ています。では、ディクショナリキーを使用してから値をフェッチし ResourceDictionary ます。 ただし、 StaticResource マークアップ拡張機能は、単一の辞書参照を実行しますが、 DynamicResource マークアップ拡張機能はディクショナリキーへのリンクを保持します。 このため、キーに関連付けられている値が置換された場合、変更はに適用され VisualElement ます。 これにより、アプリケーションでランタイムテーマを実装できるようになり Xamarin.Forms ます。

アプリケーションにランタイムテーマを実装するプロセス Xamarin.Forms は次のとおりです。

  1. 内の各テーマのリソースを定義 ResourceDictionary します。
  2. マークアップ拡張機能を使用して、アプリケーションでテーマリソースを使用し DynamicResource ます。
  3. アプリケーションの app.xaml ファイルに既定のテーマを設定します。
  4. 実行時にテーマを読み込むコードを追加します。

重要

StaticResource実行時にアプリのテーマを変更する必要がない場合は、マークアップ拡張機能を使用します。

次のスクリーンショットは、テーマが適用されたページを示しています。 iOS アプリケーションでは、明るいテーマと Android アプリケーションを使用して、ダークテーマを使用しています。

テーマが適用されたアプリのメインページで、テーマを適用したアプリのメインページの [テーマ付きアプリの詳細] ページの [テーマ付きアプリの詳細] ページの [テーマ付きアプリの詳細] ページの [テーマを適用したアプリの詳細] ページの [テーマが適用されたアプリ]ページのメインページ

Note

実行時にテーマを変更するには、XAML スタイルを使用する必要があります。現在、CSS を使用することはできません。

テーマを定義する

テーマは、に格納されているリソースオブジェクトのコレクションとして定義され ResourceDictionary ます。

次の例は、サンプルアプリケーションのを示してい LightTheme ます。

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.LightTheme">
    <Color x:Key="PageBackgroundColor">White</Color>
    <Color x:Key="NavigationBarColor">WhiteSmoke</Color>
    <Color x:Key="PrimaryColor">WhiteSmoke</Color>
    <Color x:Key="SecondaryColor">Black</Color>
    <Color x:Key="PrimaryTextColor">Black</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">Gray</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

次の例は、サンプルアプリケーションのを示してい DarkTheme ます。

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.DarkTheme">
    <Color x:Key="PageBackgroundColor">Black</Color>
    <Color x:Key="NavigationBarColor">Teal</Color>
    <Color x:Key="PrimaryColor">Teal</Color>
    <Color x:Key="SecondaryColor">White</Color>
    <Color x:Key="PrimaryTextColor">White</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">WhiteSmoke</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

ResourceDictionary には、それぞれの Color テーマを定義するリソースが含まれており、それぞれが ResourceDictionary 同一のキー値を使用します。 リソースディクショナリの詳細については、「 リソースディクショナリ」を参照してください。

重要

メソッドを呼び出すそれぞれに、分離コードファイルが必要です ResourceDictionaryInitializeComponent 。 これは、選択したテーマを表す CLR オブジェクトを実行時に作成できるようにするために必要です。

既定のテーマを設定する

アプリケーションには既定のテーマが必要であるため、コントロールには、使用するリソースの値を設定できます。 既定のテーマを設定するには、 ResourceDictionaryResourceDictionaryResourceDictionaryに定義されているアプリケーションレベルにテーマをマージします。

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>
        <ResourceDictionary Source="Themes/LightTheme.xaml" />
    </Application.Resources>
</Application>

リソースディクショナリのマージの詳細については、「マージされた リソースディクショナリ」を参照してください。

テーマリソースの使用

テーマを表すに格納されているリソースをアプリケーションが使用する場合は、 ResourceDictionary マークアップ拡張機能を使用して実行する必要があり DynamicResource ます。 これにより、実行時に別のテーマが選択された場合に、新しいテーマの値が適用されるようになります。

次の例は、オブジェクトに適用できるサンプルアプリケーションの3つのスタイルを示してい Label ます。

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>

        <Style x:Key="LargeLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource SecondaryTextColor}" />
            <Setter Property="FontSize"
                    Value="30" />
        </Style>

        <Style x:Key="MediumLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource PrimaryTextColor}" />
            <Setter Property="FontSize"
                    Value="25" />
        </Style>

        <Style x:Key="SmallLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource TertiaryTextColor}" />
            <Setter Property="FontSize"
                    Value="15" />
        </Style>

    </Application.Resources>
</Application>

これらのスタイルは、アプリケーションレベルのリソースディクショナリで定義されているので、複数のページで使用できます。 各スタイルは、マークアップ拡張機能を使用してテーマリソースを使用 DynamicResource します。

これらのスタイルは、次のページによって使用されます。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ThemingDemo"
             x:Class="ThemingDemo.UserSummaryPage"
             Title="User Summary"
             BackgroundColor="{DynamicResource PageBackgroundColor}">
    ...
    <ScrollView>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200" />
                <RowDefinition Height="120" />
                <RowDefinition Height="70" />
            </Grid.RowDefinitions>
            <Grid BackgroundColor="{DynamicResource PrimaryColor}">
                <Label Text="Face-Palm Monkey"
                       VerticalOptions="Center"
                       Margin="15"
                       Style="{StaticResource MediumLabelStyle}" />
                ...
            </Grid>
            <StackLayout Grid.Row="1"
                         Margin="10">
                <Label Text="This monkey reacts appropriately to ridiculous assertions and actions."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Cynical but not unfriendly."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Seven varieties of grimaces."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Doesn't laugh at your jokes."
                       Style="{StaticResource SmallLabelStyle}" />
            </StackLayout>
            ...
        </Grid>
    </ScrollView>
</ContentPage>

テーマリソースを直接使用する場合は、マークアップ拡張機能で使用する必要があり DynamicResource ます。 ただし、 DynamicResource マークアップ拡張機能を使用するスタイルが使用されている場合は、 StaticResource マークアップ拡張機能で使用する必要があります。

スタイル設定の詳細については、「」を参照してください Styling Xamarin.Forms Apps using XAML Styles 。 マークアップ拡張機能の詳細については DynamicResource 、「」を参照してください Dynamic Styles in Xamarin.Forms

実行時にテーマを読み込む

実行時にテーマを選択すると、アプリケーションは次のことを行う必要があります。

  1. 現在のテーマをアプリケーションから削除します。 これを行うには、 アプリケーションレベルの Xamarin_Forms _ResourceDictionary_MergedDictionaries "linktype =" absolute path ">プロパティをクリアし MergedDictionariesResourceDictionary ます。
  2. 選択したテーマを読み込みます。 これを実現するには、選択したテーマのインスタンスを MergedDictionaries アプリケーションレベルのプロパティに追加し ResourceDictionary ます。

VisualElementマークアップ拡張機能を使用してプロパティを設定するすべてのオブジェクトで、 DynamicResource 新しいテーマの値が適用されます。 これは、 DynamicResource マークアップ拡張機能がディクショナリキーへのリンクを保持しているために発生します。 そのため、キーに関連付けられている値が置換されると、その変更がオブジェクトに適用され VisualElement ます。

サンプルアプリケーションでは、を含むモーダルページを使用してテーマを選択し Picker ます。 次のコードは、 OnPickerSelectionChanged 選択したテーマが変更されたときに実行されるメソッドを示しています。

void OnPickerSelectionChanged(object sender, EventArgs e)
{
    Picker picker = sender as Picker;
    Theme theme = (Theme)picker.SelectedItem;

    ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
    if (mergedDictionaries != null)
    {
        mergedDictionaries.Clear();

        switch (theme)
        {
            case Theme.Dark:
                mergedDictionaries.Add(new DarkTheme());
                break;
            case Theme.Light:
            default:
                mergedDictionaries.Add(new LightTheme());
                break;
        }
    }
}