Design einer Xamarin.Forms Anwendung

Beispiel herunterladen Das Beispiel herunterladen

Xamarin.Forms Anwendungen können dynamisch zur Laufzeit auf Stiländerungen reagieren, indem sie die DynamicResource Markuperweiterung verwenden. Diese Markuperweiterung ähnelt der StaticResource Markuperweiterung, da beide einen Wörterbuchschlüssel verwenden, um einen Wert aus einem ResourceDictionaryabzurufen. Während die StaticResource Markuperweiterung jedoch eine einzelne Wörterbuchsuche durchführt, behält die DynamicResource Markuperweiterung einen Link zum Wörterbuchschlüssel bei. Wenn daher der dem Schlüssel zugeordnete Wert ersetzt wird, wird die Änderung auf den VisualElementangewendet. Dadurch können Laufzeitdesigns in Xamarin.Forms Anwendungen implementiert werden.

Der Prozess zum Implementieren von Runtime-Theming in einer Xamarin.Forms Anwendung sieht wie folgt aus:

  1. Definieren Sie die Ressourcen für jedes Design in einem ResourceDictionary.
  2. Verwenden Sie Designressourcen in der Anwendung mithilfe der DynamicResource Markuperweiterung.
  3. Legen Sie ein Standarddesign in der Datei App.xaml der Anwendung fest.
  4. Fügen Sie Code hinzu, um ein Design zur Laufzeit zu laden.

Wichtig

Verwenden Sie die StaticResource Markuperweiterung, wenn Sie das App-Design zur Laufzeit nicht ändern müssen.

Die folgenden Screenshots zeigen Themenseiten mit der iOS-Anwendung mit einem hellen Design und der Android-Anwendung mit einem dunklen Design:

Screenshot der Standard Seite einer Themen-App auf iOS- undScreenshot der Detailseite einer Themen-App auf iOS- und

Hinweis

Das Ändern eines Designs zur Laufzeit erfordert die Verwendung von XAML-Formatvorlagen und ist derzeit nicht mit CSS möglich.

Definieren von Designs

Ein Design ist als Auflistung von Ressourcenobjekten definiert, die in einem ResourceDictionarygespeichert sind.

Das folgende Beispiel zeigt die LightTheme aus der Beispielanwendung:

<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>

Das folgende Beispiel zeigt die DarkTheme aus der Beispielanwendung:

<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>

Jede ResourceDictionary enthält Color Ressourcen, die ihre jeweiligen Designs definieren, wobei jedes ResourceDictionary identische Schlüsselwerte verwendet. Weitere Informationen zu Ressourcenwörterbüchern finden Sie unter Ressourcenwörterbücher.

Wichtig

Für jede ResourceDictionary-Datei ist eine CodeBehind-Datei erforderlich, die die InitializeComponent -Methode aufruft. Dies ist erforderlich, damit zur Laufzeit ein CLR-Objekt erstellt werden kann, das das ausgewählte Design darstellt.

Festlegen eines Standarddesigns

Für eine Anwendung ist ein Standarddesign erforderlich, sodass Steuerelemente Werte für die Ressourcen aufweisen, die sie verbrauchen. Ein Standarddesign kann festgelegt werden, indem sie das Design ResourceDictionary mit der Anwendungsebene ResourceDictionary zusammenführen, die in App.xaml definiert ist:

<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>

Weitere Informationen zum Zusammenführen von Ressourcenwörterbüchern finden Sie unter Zusammengeführte Ressourcenwörterbücher.

Verwenden von Designressourcen

Wenn eine Anwendung eine Ressource nutzen möchte, die in einer ResourceDictionary gespeichert ist, die ein Design darstellt, sollte dies mit der DynamicResource Markuperweiterung getan werden. Dadurch wird sichergestellt, dass die Werte aus dem neuen Design angewendet werden, wenn zur Laufzeit ein anderes Design ausgewählt wird.

Das folgende Beispiel zeigt drei Stile aus der Beispielanwendung, die auf Label Objekte angewendet werden können:

<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>

Diese Stile werden im Ressourcenwörterbuch auf Anwendungsebene definiert, sodass sie von mehreren Seiten genutzt werden können. Jede Formatvorlage nutzt Designressourcen mit der DynamicResource Markuperweiterung.

Diese Stile werden dann von Seiten genutzt:

<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>

Wenn eine Designressource direkt genutzt wird, sollte sie mit der DynamicResource Markuperweiterung genutzt werden. Wenn jedoch eine Formatvorlage verwendet wird, die die DynamicResource Markuperweiterung verwendet, sollte sie mit der StaticResource Markuperweiterung verwendet werden.

Weitere Informationen zum Formatieren finden Sie unter Formatieren Xamarin.Forms von Apps mit XAML-Formatvorlagen. Weitere Informationen zur DynamicResource Markuperweiterung finden Sie unter Dynamische Stile in Xamarin.Forms.

Laden eines Designs zur Laufzeit

Wenn zur Laufzeit ein Design ausgewählt wird, sollte die Anwendung Folgendes ausführen:

  1. Entfernen Sie das aktuelle Design aus der Anwendung. Dies wird erreicht, indem die MergedDictionaries Eigenschaft der Anwendungsebene ResourceDictionaryentfernt wird.
  2. Laden Sie das ausgewählte Design. Dies wird erreicht, indem der Eigenschaft der Anwendungsebene ResourceDictionaryein instance des ausgewählten Designs MergedDictionaries hinzugefügt wird.

Alle VisualElement Objekte, die Eigenschaften mit der DynamicResource Markuperweiterung festlegen, wenden dann die neuen Designwerte an. Dies tritt auf, weil die DynamicResource Markuperweiterung einen Link zu Wörterbuchschlüsseln beibehält. Wenn die mit Schlüsseln verknüpften Werte ersetzt werden, werden die Änderungen daher auf die VisualElement -Objekte angewendet.

In der Beispielanwendung wird ein Design über eine modale Seite ausgewählt, die einen Pickerenthält. Der folgende Code zeigt die OnPickerSelectionChanged Methode, die ausgeführt wird, wenn sich das ausgewählte Design ändert:

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;
        }
    }
}