Бөлісу құралы:


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 с темной темой:

Снимок экрана: главная страница тематических приложений в iOS и AndroidСнимок экрана: страница сведений о тематических приложениях в iOS и Android

Примечание.

Изменение темы во время выполнения требует использования стилей 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 используются одинаковые значения ключей. Дополнительные сведения о словарях ресурсов см. в разделах "Словари ресурсов".

Внимание

Для каждого ResourceDictionaryфайла, вызывающего метод, требуется код за файлом InitializeComponent . Это необходимо, чтобы объект CLR, представляющий выбранную тему, можно создать во время выполнения.

Настройка темы по умолчанию

Для приложения требуется тема по умолчанию, чтобы элементы управления имели значения для используемых ресурсов. Тему по умолчанию можно задать, объединив тему ResourceDictionary на уровень ResourceDictionary приложения, определенный в App.xaml:

<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 разметки. Это гарантирует, что при выборе другой темы во время выполнения будут применены значения из новой темы.

В следующем примере показаны три стиля из примера приложения, которое можно применить к 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 разметки.

Дополнительные сведения о стили см. в статье "Стили стилей Xamarin.Forms XAML". Дополнительные сведения о расширении разметки см. в Xamarin.Formsразделе "Динамические DynamicResource стили".

Загрузка темы во время выполнения

Если тема выбрана во время выполнения, приложение должно:

  1. Удалите текущую тему из приложения. Это достигается путем очистки MergedDictionaries свойства уровня ResourceDictionaryприложения.
  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;
        }
    }
}