Motiv aplikace
Aplikace .NET Multi-Platform App UI (.NET MAUI) můžou dynamicky reagovat na změny stylu za běhu pomocí DynamicResource
rozšíření značek. Toto rozšíření značek je podobné StaticResource
rozšíření značek, v tom, že obě používají klíč slovníku k načtení hodnoty z objektu ResourceDictionary. Zatímco StaticResource
rozšíření značek provádí jedno vyhledávání slovníku, DynamicResource
rozšíření značek udržuje odkaz na klíč slovníku. Proto pokud je hodnota přidružená ke klíči nahrazena, změna se použije na VisualElementhodnotu . To umožňuje implementaci motivů za běhu v aplikacích .NET MAUI.
Proces implementace motivů runtime v aplikaci .NET MAUI je následující:
- Definujte prostředky pro každý motiv v souboru ResourceDictionary. Další informace najdete v tématu Definování motivů.
- Nastavte výchozí motiv v souboru App.xaml aplikace. Další informace najdete v tématu Nastavení výchozího motivu.
- Využití prostředků motivu v aplikaci pomocí
DynamicResource
rozšíření značek Další informace najdete v tématu Využití prostředků motivu. - Přidejte kód pro načtení motivu za běhu. Další informace najdete v tématu Načtení motivu za běhu.
Důležité
StaticResource
Rozšíření značek použijte, pokud vaše aplikace nemusí dynamicky měnit motivy za běhu. Pokud očekáváte přepínání motivů v době, kdy je aplikace spuštěná, použijte DynamicResource
rozšíření značek, které umožňuje aktualizovat prostředky za běhu.
Následující snímek obrazovky ukazuje motivované stránky s aplikací pro iOS, která používá světlý motiv a aplikaci pro Android pomocí tmavého motivu:
Poznámka:
Změna motivu za běhu vyžaduje použití definic stylů XAML nebo C# a není možné použít šablony stylů CSS.
.NET MAUI má také možnost reagovat na změny systémového motivu. Motiv systému se může změnit z různých důvodů v závislosti na konfiguraci zařízení. To zahrnuje explicitní změnu systémového motivu uživatelem, změnu v důsledku denního času a změnu kvůli faktorům prostředí, jako je nízké světlo. Další informace najdete v tématu Reakce na změny systémového motivu.
Definování motivů
Motiv je definován jako kolekce objektů prostředků uložených v objektu ResourceDictionary.
Následující příklad ukazuje ResourceDictionary pro světlý motiv s názvem 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>
Následující příklad ukazuje ResourceDictionary tmavý motiv s názvem 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ždý ResourceDictionary obsahuje Color prostředky, které definují příslušné motivy, přičemž každý z nich ResourceDictionary používá stejné klíčové hodnoty. Další informace o slovníkech prostředků najdete v tématu Slovníky zdrojů.
Důležité
Pro každý ResourceDictionary, který volá metodu, se vyžaduje kód za souborem InitializeComponent
. To je nezbytné, aby bylo možné vytvořit objekt CLR představující vybraný motiv za běhu.
Nastavení výchozího motivu
Aplikace vyžaduje výchozí motiv, aby ovládací prvky měly hodnoty pro prostředky, které spotřebovávají. Výchozí motiv lze nastavit sloučením motivu ResourceDictionary do úrovně ResourceDictionary aplikace definované v 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>
Další informace o slučování slovníků prostředků najdete v tématu Slovníky sloučených prostředků.
Využívání prostředků motivu
Když chce aplikace využívat prostředek uložený v motivu ResourceDictionary , měl by to udělat s rozšířením DynamicResource
značek. Tím se zajistí, že pokud je za běhu vybraný jiný motiv, použijí se hodnoty z nového motivu.
Následující příklad ukazuje tři styly z toho, které lze použít pro všechny Label objekty v aplikaci:
<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>
Tyto styly jsou definovány ve slovníku prostředků na úrovni aplikace, aby je bylo možné využívat více stránkami. Každý styl využívá prostředky motivu s rozšířením DynamicResource
značek.
Tyto styly pak využívají stránky:
<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=" • Cynical but not unfriendly."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Seven varieties of grimaces."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Doesn't laugh at your jokes."
Style="{StaticResource SmallLabelStyle}" />
</StackLayout>
...
</Grid>
</ScrollView>
</ContentPage>
Když se prostředek motivu spotřebovává přímo, měl by být spotřebován s rozšířením DynamicResource
značek. Pokud je však spotřebován styl, který používá DynamicResource
rozšíření značek, měl by být spotřebován s rozšířením StaticResource
značek.
Další informace o stylu najdete v tématu Aplikace stylů pomocí XAML. Další informace o DynamicResource
rozšíření značek naleznete v tématu Dynamické styly.
Načtení motivu za běhu
Když je motiv vybraný za běhu, měla by aplikace:
- Odeberte aktuální motiv z aplikace. Toho dosáhnete vymazáním
MergedDictionaries
vlastnosti na úrovni ResourceDictionaryaplikace . - Načtěte vybraný motiv. Toho dosáhnete přidáním instance vybraného motivu do
MergedDictionaries
vlastnosti úrovně ResourceDictionaryaplikace .
Všechny VisualElement objekty, které nastavují vlastnosti s rozšířením DynamicResource
značek, pak použijí nové hodnoty motivu. K tomu dochází, protože DynamicResource
rozšíření značek udržuje odkaz na klíče slovníku. Proto při nahrazení hodnot přidružených ke klíčům se změny použijí na VisualElement objekty.
V ukázkové aplikaci je motiv vybrán prostřednictvím modální stránky, která obsahuje Picker. Následující kód ukazuje metodu OnPickerSelectionChanged
, která se spustí při změně vybraného motivu:
Následující příklad ukazuje odebrání aktuálního motivu a načtení nového motivu:
ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
mergedDictionaries.Clear();
mergedDictionaries.Add(new DarkTheme());
}