Udostępnij za pośrednictwem


Motyw aplikacji

Przeglądaj przykład. Przeglądanie przykładu

Aplikacje interfejsu użytkownika aplikacji wieloplatformowych platformy .NET (.NET MAUI) mogą reagować na zmiany stylu dynamicznie w czasie wykonywania przy użyciu DynamicResource rozszerzenia znaczników. To rozszerzenie znaczników jest podobne do StaticResource rozszerzenia znaczników, w tym oba używają klucza słownika do pobierania wartości z klasy ResourceDictionary. Jednak podczas gdy StaticResource rozszerzenie znaczników wykonuje wyszukiwanie pojedynczego słownika, DynamicResource rozszerzenie znaczników utrzymuje link do klucza słownika. W związku z tym, jeśli wartość skojarzona z kluczem zostanie zamieniona, zmiana zostanie zastosowana do elementu VisualElement. Umożliwia to implementowanie motywów środowiska uruchomieniowego w aplikacjach MAUI platformy .NET.

Proces implementowania motywów środowiska uruchomieniowego w aplikacji .NET MAUI jest następujący:

  1. Zdefiniuj zasoby dla każdego motywu w obiekcie ResourceDictionary. Aby uzyskać więcej informacji, zobacz Definiowanie motywów.
  2. Ustaw motyw domyślny w pliku App.xaml aplikacji. Aby uzyskać więcej informacji, zobacz Ustawianie motywu domyślnego.
  3. Korzystanie z zasobów motywu w aplikacji przy użyciu DynamicResource rozszerzenia znaczników. Aby uzyskać więcej informacji, zobacz Korzystanie z zasobów motywu.
  4. Dodaj kod, aby załadować motyw w czasie wykonywania. Aby uzyskać więcej informacji, zobacz Ładowanie motywu w czasie wykonywania.

Ważne

StaticResource Użyj rozszerzenia znaczników, jeśli aplikacja nie musi dynamicznie zmieniać motywów w czasie wykonywania. Jeśli przewidujesz przełączanie motywów podczas działania aplikacji, użyj DynamicResource rozszerzenia znaczników, które umożliwia aktualizowanie zasobów w czasie wykonywania.

Poniższy zrzut ekranu przedstawia strony motywowe z aplikacją dla systemu iOS przy użyciu motywu jasnego i aplikacji dla systemu Android przy użyciu motywu ciemnego:

Zrzut ekranu przedstawiający stronę główną aplikacji tematyce.

Uwaga

Zmiana motywu w czasie wykonywania wymaga użycia definicji stylów XAML lub C# i nie jest możliwa przy użyciu arkuszy CSS.

Program .NET MAUI ma również możliwość reagowania na zmiany motywu systemu. Motyw systemowy może ulec zmianie z różnych powodów, w zależności od konfiguracji urządzenia. Obejmuje to jawną zmianę motywu systemowego przez użytkownika, zmianę z powodu pory dnia i zmianę z powodu czynników środowiskowych, takich jak małe światło. Aby uzyskać więcej informacji, zobacz Reagowanie na zmiany motywu systemowego.

Definiowanie motywów

Motyw jest definiowany jako kolekcja obiektów zasobów przechowywanych w obiekcie ResourceDictionary.

W poniższym przykładzie pokazano ResourceDictionary element dla motywu lekkiego o nazwie LightTheme:

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    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>

W poniższym przykładzie pokazano dla ResourceDictionary motywu ciemnego o nazwie DarkTheme:

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    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>

Każdy zawiera Color zasoby, które definiują odpowiednie motywy, z których każda ResourceDictionary ResourceDictionary używa identycznych wartości klucza. Aby uzyskać więcej informacji na temat słowników zasobów, zobacz Słowniki zasobów.

Ważne

Kod za plikiem jest wymagany dla każdego ResourceDictionaryobiektu , który wywołuje metodę InitializeComponent . Jest to konieczne, aby obiekt CLR reprezentujący wybrany motyw można utworzyć w czasie wykonywania.

Ustawianie motywu domyślnego

Aplikacja wymaga motywu domyślnego, aby kontrolki miały wartości dla używanych zasobów. Motyw domyślny można ustawić, scalając motyw ResourceDictionary na poziomie ResourceDictionary aplikacji zdefiniowanym w pliku App.xaml:

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

Aby uzyskać więcej informacji na temat scalania słowników zasobów, zobacz Scalone słowniki zasobów.

Korzystanie z zasobów motywu

Gdy aplikacja chce korzystać z zasobu przechowywanego w obiekcie reprezentującym ResourceDictionary motyw, powinien to zrobić za DynamicResource pomocą rozszerzenia znaczników. Gwarantuje to, że w przypadku wybrania innego motywu w czasie wykonywania zostaną zastosowane wartości z nowego motywu.

W poniższym przykładzie przedstawiono trzy style, które można zastosować do wszystkich Label obiektów w aplikacji:

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             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>

Te style są definiowane w słowniku zasobów na poziomie aplikacji, dzięki czemu mogą być używane przez wiele stron. Każdy styl używa zasobów motywu DynamicResource z rozszerzeniem znaczników.

Te style są następnie używane przez strony:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             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>

Jeśli zasób motywu jest używany bezpośrednio, powinien być używany z DynamicResource rozszerzeniem znaczników. Jeśli jednak używany jest styl używający DynamicResource rozszerzenia znaczników, powinien być używany z StaticResource rozszerzeniem znaczników.

Aby uzyskać więcej informacji na temat stylów, zobacz Style apps using XAML (Aplikacje stylów używające języka XAML). Aby uzyskać więcej informacji na temat DynamicResource rozszerzenia znaczników, zobacz Style dynamiczne.

Ładowanie motywu w czasie wykonywania

Po wybraniu motywu w czasie wykonywania aplikacja powinna:

  1. Usuń bieżący motyw z aplikacji. Jest to osiągane przez wyczyszczenie MergedDictionaries właściwości na poziomie ResourceDictionaryaplikacji .
  2. Załaduj wybrany motyw. Jest to osiągane przez dodanie wystąpienia wybranego motywu do MergedDictionaries właściwości na poziomie ResourceDictionaryaplikacji .

Wszystkie VisualElement obiekty, które ustawiają właściwości z DynamicResource rozszerzeniem znaczników, będą następnie stosować nowe wartości motywu. Dzieje się tak, ponieważ DynamicResource rozszerzenie znaczników utrzymuje link do kluczy słownika. W związku z tym po zastąpieniu wartości skojarzonych z kluczami zmiany są stosowane do VisualElement obiektów.

W przykładowej aplikacji motyw jest wybierany za pośrednictwem strony modalnej zawierającej Pickerelement . Poniższy kod przedstawia metodę OnPickerSelectionChanged , która jest wykonywana po zmianie wybranego motywu:

W poniższym przykładzie pokazano usunięcie bieżącego motywu i załadowanie nowego motywu:

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