Estilos dinâmicos em Xamarin.Forms

Baixar exemplo Baixar o exemplo

Os estilos não respondem a alterações de propriedade e permanecem inalterados durante a duração de um aplicativo. Por exemplo, depois de atribuir um Style a um elemento visual, se uma das instâncias Setter for modificada, removida ou uma nova instância Setter adicionada, as alterações não serão aplicadas ao elemento visual. No entanto, os aplicativos podem responder a alterações de estilo dinamicamente em runtime usando recursos dinâmicos.

A DynamicResource extensão de marcação é semelhante à StaticResource extensão de marcação em que ambos usam uma chave de dicionário para buscar um valor de um ResourceDictionary. No entanto, enquanto o StaticResource executa uma única pesquisa de dicionário, o DynamicResource mantém um link para a chave do dicionário. Portanto, se a entrada de dicionário associada à chave for substituída, a alteração será aplicada ao elemento visual. Isso permite que as alterações de estilo de runtime sejam feitas em um aplicativo.

O exemplo de código a seguir demonstra estilos dinâmicos em uma página XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesPage" Title="Dynamic" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle"
                   TargetType="SearchBar"
                   BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle"
                   TargetType="SearchBar">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Placeholder="These SearchBar controls"
                       Style="{DynamicResource searchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

As SearchBar instâncias usam a DynamicResource extensão de marcação para fazer referência a um Style chamado searchBarStyle, que não está definido no XAML. No entanto, como as Style propriedades das SearchBar instâncias são definidas usando um DynamicResource, a chave de dicionário ausente não resulta na geração de uma exceção.

Em vez disso, no arquivo code-behind, o construtor cria uma ResourceDictionary entrada com a chave searchBarStyle, conforme mostrado no exemplo de código a seguir:

public partial class DynamicStylesPage : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPage ()
    {
        InitializeComponent ();
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
    }

    void OnButtonClicked (object sender, EventArgs e)
    {
        if (originalStyle) {
            Resources ["searchBarStyle"] = Resources ["greenSearchBarStyle"];
            originalStyle = false;
        } else {
            Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
            originalStyle = true;
        }
    }
}

Quando o OnButtonClicked manipulador de eventos for executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle. Isso resulta na aparência mostrada nas capturas de tela seguir:

Exemplo de estilo dinâmico azul Exemplode estilo dinâmico verde

O exemplo de código a seguir demonstra a página equivalente em C#:

public class DynamicStylesPageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        ...
        var searchBar1 = new SearchBar { Placeholder = "These SearchBar controls" };
        searchBar1.SetDynamicResource (VisualElement.StyleProperty, "searchBarStyle");
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = { searchBar1, searchBar2, searchBar3, searchBar4,    button    }
        };
    }
    ...
}

Em C#, as SearchBar instâncias usam o SetDynamicResource método para referenciar searchBarStyle. O OnButtonClicked código do manipulador de eventos é idêntico ao exemplo de XAML e, quando executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle.

Herança de estilo dinâmico

Derivar um estilo de um estilo dinâmico não pode ser obtido usando a Style.BasedOn propriedade . Em vez disso, a Style classe inclui a BaseResourceKey propriedade , que pode ser definida como uma chave de dicionário cujo valor pode ser alterado dinamicamente.

O exemplo de código a seguir demonstra a herança de estilo dinâmico em uma página XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesInheritancePage" Title="Dynamic Inheritance" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle" TargetType="SearchBar" BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle" TargetType="SearchBar">
              ...
            </Style>
            <Style x:Key="tealSearchBarStyle" TargetType="SearchBar" BaseResourceKey="searchBarStyle">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Text="These SearchBar controls" Style="{StaticResource tealSearchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

As SearchBar instâncias usam a StaticResource extensão de marcação para fazer referência a um Style nomeado tealSearchBarStyle. Isso Style define algumas propriedades adicionais e usa a BaseResourceKey propriedade para referenciar searchBarStyle. A DynamicResource extensão de marcação não é necessária porque tealSearchBarStyle não será alterada, exceto pela Style derivada dela. Portanto, tealSearchBarStyle mantém um link para searchBarStyle e é alterado quando o estilo base é alterado.

No arquivo code-behind, o construtor cria uma ResourceDictionary entrada com a chave searchBarStyle, de acordo com o exemplo anterior que demonstrou estilos dinâmicos. Quando o OnButtonClicked manipulador de eventos for executado, searchBarStyle alternará entre blueSearchBarStyle e greenSearchBarStyle. Isso resulta na aparência mostrada nas capturas de tela seguir:

Exemplo de herança de estilo dinâmico azul Exemplode herança de estilo dinâmico verde

O exemplo de código a seguir demonstra a página equivalente em C#:

public class DynamicStylesInheritancePageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesInheritancePageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var tealSearchBarStyle = new Style (typeof(SearchBar)) {
            BaseResourceKey = "searchBarStyle",
            ...
        };
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = {
                new SearchBar { Text = "These SearchBar controls", Style = tealSearchBarStyle },
                ...
            }
        };
    }
    ...
}

O tealSearchBarStyle é atribuído diretamente à Style propriedade das SearchBar instâncias. Isso Style define algumas propriedades adicionais e usa a BaseResourceKey propriedade para referenciar searchBarStyle. O SetDynamicResource método não é necessário aqui porque tealSearchBarStyle não será alterado, exceto pelo Style do qual ele deriva. Portanto, tealSearchBarStyle mantém um link para searchBarStyle e é alterado quando o estilo base é alterado.

Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.