Share via


Thème d’une Xamarin.Forms application

Xamarin.Forms les applications peuvent répondre aux modifications de style dynamiquement au moment de l’exécution à l’aide de l’extension de DynamicResource balisage. Cette extension de balisage est similaire à l’extension de StaticResource balisage, dans laquelle les deux utilisent une clé de dictionnaire pour extraire une valeur d’un ResourceDictionary. Toutefois, alors que l’extension de StaticResource balisage effectue une recherche de dictionnaire unique, l’extension de DynamicResource balisage conserve un lien vers la clé de dictionnaire. Par conséquent, si la valeur associée à la clé est remplacée, la modification est appliquée au VisualElement. Cela permet à l’exécution de thèmes d’être implémentés dans les Xamarin.Forms applications.

Le processus d’implémentation de thèmes d’exécution dans une Xamarin.Forms application est le suivant :

  1. Définissez les ressources pour chaque thème dans un ResourceDictionary.
  2. Consommez des ressources de thème dans l’application à l’aide de l’extension de DynamicResource balisage.
  3. Définissez un thème par défaut dans le fichier App.xaml de l’application.
  4. Ajoutez du code pour charger un thème au moment de l’exécution.

Important

Utilisez l’extension de StaticResource balisage si vous n’avez pas besoin de modifier le thème de l’application au moment de l’exécution.

Les captures d’écran suivantes montrent des pages thématiques, avec l’application iOS à l’aide d’un thème clair et de l’application Android à l’aide d’un thème sombre :

Capture d’écran de la page principale d’une application en thème, sur iOS et AndroidCapture d’écran de la page de détails d’une application en thème, sur iOS et Android

Remarque

La modification d’un thème au moment de l’exécution nécessite l’utilisation de styles XAML et n’est actuellement pas possible à l’aide de CSS.

Définir des thèmes

Un thème est défini comme une collection d’objets de ressources stockés dans un ResourceDictionary.

L’exemple suivant montre l’exemple LightTheme d’application :

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

L’exemple suivant montre l’exemple DarkTheme d’application :

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

Chacun ResourceDictionary contient des Color ressources qui définissent leurs thèmes respectifs, chacune utilisant des ResourceDictionary valeurs de clé identiques. Pour plus d’informations sur les dictionnaires de ressources, consultez Dictionnaires de ressources.

Important

Un fichier code-behind est requis pour chacun d’eux ResourceDictionary, qui appelle la InitializeComponent méthode. Cela est nécessaire afin qu’un objet CLR représentant le thème choisi puisse être créé au moment de l’exécution.

Définir un thème par défaut

Une application requiert un thème par défaut afin que les contrôles aient des valeurs pour les ressources qu’elles consomment. Vous pouvez définir un thème par défaut en fusionnant le thème dans le niveau de l’application ResourceDictionary défini dans App.xaml :ResourceDictionary

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

Pour plus d’informations sur la fusion des dictionnaires de ressources, consultez Dictionnaires de ressources fusionnés.

Consommer des ressources de thème

Lorsqu’une application souhaite consommer une ressource stockée dans un ResourceDictionary thème qui représente un thème, elle doit le faire avec l’extension de DynamicResource balisage. Cela garantit que si un thème différent est sélectionné au moment de l’exécution, les valeurs du nouveau thème sont appliquées.

L’exemple suivant montre trois styles de l’exemple d’application qui peut être appliqué aux Label objets :

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

Ces styles sont définis dans le dictionnaire de ressources au niveau de l’application, afin qu’ils puissent être consommés par plusieurs pages. Chaque style utilise des ressources de thème avec l’extension de DynamicResource balisage.

Ces styles sont ensuite consommés par les pages :

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

Lorsqu’une ressource de thème est consommée directement, elle doit être consommée avec l’extension de DynamicResource balisage. Toutefois, lorsqu’un style qui utilise l’extension de DynamicResource balisage est consommé, il doit être consommé avec l’extension de StaticResource balisage.

Pour plus d’informations sur le style, consultez Applications Xamarin.Forms de style à l’aide de styles XAML. Pour plus d’informations sur l’extension de DynamicResource balisage, consultez Styles dynamiques dans Xamarin.Forms.

Charger un thème au moment de l’exécution

Lorsqu’un thème est sélectionné au moment de l’exécution, l’application doit :

  1. Supprimez le thème actuel de l’application. Pour ce faire, effacez la MergedDictionaries propriété du niveau ResourceDictionaryapplication.
  2. Chargez le thème sélectionné. Pour ce faire, ajoutez une instance du thème sélectionné à la MergedDictionaries propriété du niveau ResourceDictionaryapplication.

Tous les VisualElement objets qui définissent des propriétés avec l’extension DynamicResource de balisage appliquent ensuite les nouvelles valeurs de thème. Cela se produit parce que l’extension de DynamicResource balisage conserve un lien vers des clés de dictionnaire. Par conséquent, lorsque les valeurs associées aux clés sont remplacées, les modifications sont appliquées aux VisualElement objets.

Dans l’exemple d’application, un thème est sélectionné via une page modale qui contient un Picker. Le code suivant montre la OnPickerSelectionChanged méthode, qui est exécutée lorsque le thème sélectionné change :

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