Tema di un'applicazione Xamarin.Forms

Download Sample Scaricare l'esempio

Xamarin.Forms le applicazioni possono rispondere alle modifiche di stile in modo dinamico in fase di esecuzione usando l'estensione di DynamicResource markup. Questa estensione di markup è simile all'estensione StaticResource di markup, in quanto entrambi usano una chiave del dizionario per recuperare un valore da un oggetto ResourceDictionary. Tuttavia, mentre l'estensione StaticResource di markup esegue una ricerca in un singolo dizionario, l'estensione DynamicResource di markup mantiene un collegamento alla chiave del dizionario. Pertanto, se il valore associato alla chiave viene sostituito, la modifica viene applicata a VisualElement. In questo modo è possibile implementare il tema di runtime nelle Xamarin.Forms applicazioni.

Il processo di implementazione del tema di runtime in un'applicazione Xamarin.Forms è il seguente:

  1. Definire le risorse per ogni tema in un oggetto ResourceDictionary.
  2. Utilizzare le risorse del tema nell'applicazione usando l'estensione di DynamicResource markup.
  3. Impostare un tema predefinito nel file App.xaml dell'applicazione.
  4. Aggiungere codice per caricare un tema in fase di esecuzione.

Importante

Usare l'estensione StaticResource di markup se non è necessario modificare il tema dell'app in fase di esecuzione.

Gli screenshot seguenti mostrano pagine con tema tema, con l'applicazione iOS usando un tema chiaro e l'applicazione Android usando un tema scuro:

Screenshot of the main page of a themed app, on iOS and AndroidScreenshot of the detail page of a themed app, on iOS and Android

Nota

La modifica di un tema in fase di esecuzione richiede l'uso degli stili XAML e non è attualmente possibile tramite CSS.

Definire i temi

Un tema viene definito come una raccolta di oggetti risorsa archiviati in un oggetto ResourceDictionary.

L'esempio seguente illustra l'oggetto LightTheme dell'applicazione di esempio:

<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'esempio seguente illustra l'oggetto DarkTheme dell'applicazione di esempio:

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

Ogni ResourceDictionary contiene Color risorse che definiscono i rispettivi temi, ognuna ResourceDictionary con valori di chiave identici. Per altre informazioni sui dizionari risorse, vedere Dizionari risorse.

Importante

Per ogni ResourceDictionaryoggetto è necessario un file code-behind che chiama il InitializeComponent metodo . Questa operazione è necessaria in modo che sia possibile creare un oggetto CLR che rappresenta il tema scelto in fase di esecuzione.

Impostare un tema predefinito

Un'applicazione richiede un tema predefinito, in modo che i controlli abbiano valori per le risorse utilizzate. È possibile impostare un tema predefinito unendo il tema a livello ResourceDictionary di ResourceDictionary applicazione definito in 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>

Per altre informazioni sull'unione di dizionari risorse, vedere Dizionari risorse uniti.

Utilizzare le risorse del tema

Quando un'applicazione vuole utilizzare una risorsa archiviata in un ResourceDictionary oggetto che rappresenta un tema, deve farlo con l'estensione DynamicResource di markup. In questo modo si garantisce che, se in fase di esecuzione è selezionato un tema diverso, verranno applicati i valori del nuovo tema.

L'esempio seguente illustra tre stili dell'applicazione di esempio che possono essere applicati agli Label oggetti :

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

Questi stili vengono definiti nel dizionario risorse a livello di applicazione, in modo che possano essere utilizzati da più pagine. Ogni stile utilizza le risorse del tema con l'estensione di DynamicResource markup.

Questi stili vengono quindi utilizzati dalle pagine:

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

Quando una risorsa del tema viene utilizzata direttamente, deve essere utilizzata con l'estensione di DynamicResource markup. Tuttavia, quando viene utilizzato uno stile che usa l'estensione DynamicResource di markup, deve essere utilizzato con l'estensione di StaticResource markup.

Per altre informazioni sullo stile, vedi Applicazione Xamarin.Forms di stili alle app con stili XAML. Per altre informazioni sull'estensione DynamicResource di markup, vedere Stili dinamici in Xamarin.Forms.

Caricare un tema in fase di esecuzione

Quando un tema viene selezionato in fase di esecuzione, l'applicazione deve:

  1. Rimuovere il tema corrente dall'applicazione. Questa operazione viene ottenuta cancellando la MergedDictionaries proprietà a livello ResourceDictionarydi applicazione .
  2. Caricare il tema selezionato. A tale scopo, aggiungere un'istanza del tema selezionato alla MergedDictionaries proprietà del livello ResourceDictionaryapplicazione .

Tutti VisualElement gli oggetti che impostano le proprietà con l'estensione DynamicResource di markup applicheranno quindi i nuovi valori del tema. Ciò si verifica perché l'estensione DynamicResource di markup gestisce un collegamento alle chiavi del dizionario. Pertanto, quando i valori associati alle chiavi vengono sostituiti, le modifiche vengono applicate agli VisualElement oggetti .

Nell'applicazione di esempio viene selezionato un tema tramite una pagina modale che contiene un oggetto Picker. Il codice seguente mostra il OnPickerSelectionChanged metodo , che viene eseguito quando cambia il tema selezionato:

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