Xamarin.Forms - Usando Resources e ResourceDictionary

 

Neste artigo vou apresentar o conceito de Resources em aplicações Xamarin Forms.   

Resources é um conceito muito importante usado em aplicações Xamarin Forms.



Os Resources permitem compartilhar definições comuns em todo um aplicativo para ajudá-lo a reduzir valores codificados em seu código, facilitando assim a manutenção do código.

Dessa forma, ao usar Resources, ao invés de ter que alterar todos os valores em seu aplicativo quando um tema muda, você só terá que alterar um lugar: o recurso.

Um exemplo onde podemos usar Resources é quando temos valores duplicados para a mesma propriedade :

....
<Label Text="Nome" BackgroundColor="White" TextColor="Blue" FontSize="24" />
<Label Text="Email" BackgroundColor="White" TextColor="Blue" FontSize="24" />
<Entry BackgroundColor="White" TextColor="Blue" />
<Button Text="Gravar" BackgroundColor="White" TextColor="Blue" FontSize="24"/>
...

Geralmente definimos Resources agrupados e armazenados em um ResourceDictionary, que é um repositório para recursos que são usados pela aplicação Xamarin.Forms.

Os recursos típicos armazenados em um ResourceDictionary incluem : estilos, templates de controles, data templates, cores, e conversores.

Um ResourceDictionary utiliza um par de chaves key-value para armazenar as informações, assim no código XAML você terá que fornecer a palavra-chave x:Key para cada recurso definido.

...
<Color x:Key="backgroundColor">#33302E</Color>
<Color x:Key="textColor">White</Color>
<x:Double x:Key="fontSize">24</x:Double>
...

Podemos definir e usar recursos tanto usando XAML como código C#.

No XAML, os recursos são definidos em um ResourceDictionary e depois recuperados e aplicados aos elementos usando a extensão de marcação StaticResource.

<Application
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Teste.App">
    <Application.Resources>
          <ResourceDictionary>
		<Color x:Key="backgroundColor">#33302E</Color>
		<Color x:Key="textColor">White</Color>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Em C#, os recursos são definidos em um ResourceDictionary e, em seguida, recuperados e aplicados a elementos usando um indexador baseado em texto.

   ....
  this.Resources =new ResourceDictionary();
  this.Resources["buttonFontSize"] = 20;
   ...
 

No entanto, há pouca vantagem de usar um ResourceDictionary em C#, visto que os recursos podem facilmente ser diretamente atribuídos às propriedades dos elementos visuais sem ter que primeiro recuperá-los a partir de um ResourceDictionary.

Os Resources podem ser definidos em um ResourceDictionary que é anexado à coleção Resources de uma página ou controle, ou para a coleção Resources da Aplicação.

Quando você escolher onde vai definir o ResourceDictionary vai impactar onde ele poderá ser usado.

Assim temos os escopos a nível de controle, página e aplicação para o ResourceDictionary:

  • Quando definido a nível de controle podem se somente aplicados para o controle e seus filhos;
  • Quando definido a nível de página podem somente ser aplicados à página e suas view filhas;
  • Quando definido a nível de aplicação podem ser aplicados em toda a aplicação;

Vamos a seguir mostrar na prática um exemplo do uso de ResourceDictionary e utilizar a marcação StaticResource que permite referenciar recursos predefinidos.

Criando e consumindo um ResourceDictionary

Abra o Visual Studio Community 2015 e clique em New Project;

Selecione Visual C#, o template Cross Plataform e a seguir Blank App (Xamarin.Forms Portable);

NotaA opção Portable (Portable Class Library - PCL ) - Inclui todo o código comum em uma biblioteca de vínculo dinâmico (DLL) que pode então ser referenciada a partir de outros projetos;

Informe o nome App_ResourceDictionary e clique no botão OK;

Incluindo uma nova página XAML no projeto compartilhado (Portable)

Selecione o projeto App_ListView1(Portable) e no menu Project clique em Add New Item;

Selecione o template Cross Plataform -> Forms Xaml Page e informe o nome ResourceDictionaryPage.xaml e clique em Add;

Lembre-se que agora precisamos alterar o código da classe App.cs para criar uma instância da nossa página ListViewPagina4 definindo-a como a página principal que será executada quando a aplicação rodar. O código deve ficar assim:

using Xamarin.Forms;
namespace App_ListView1
{
    public class App : Application
    {
        public App()
        {
            MainPage = new ResourceDictionaryPage();
        }
      .....
}

Agora podemos definir o código no arquivo ResourceDictionaryPage.xaml conforme mostrado a seguir:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App_ResourceDictionary.ResourceDictionartyPage">
    <StackLayout BackgroundColor="Aqua">
        <Label Text="Macoratti .net"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            TextColor="Blue"
            FontSize="20"
            />
        <Label Text="Quase tudo para .Net"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            TextColor="Blue"
            FontSize="20"
            />
        <Button Text="Exemplo de uso"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            BorderWidth="3"
            FontSize="18"
            TextColor="Red"
            Font="Large" />
        <Button Text="de ResourceDictionary"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            BorderWidth="3"
            FontSize="18"
            TextColor="Red"
            Font="Large" />
    </StackLayout>
</ContentPage>

Observe que temos muitas propriedades com valores repetidos, e vamos usar um ResourceDictionary a nível de página, para aplicar os valores a todas as views da página.

Vamos então alterar o código conforme mostrado a seguir:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App_ResourceDictionary.ResourceDictionaryPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="layoutBackgroundColor">Yellow</Color>
            <Color x:Key="labelTextColor">Blue</Color>
            <Color x:Key="buttonTextColor">Red</Color>
            <x:Double x:Key="labelFontSize">20</x:Double>
            <x:Double x:Key="buttonFontSize">18</x:Double>
            <x:Double x:Key="buttonBorderWidth">3</x:Double>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout 
        BackgroundColor="{StaticResource layoutBackgroundColor}">
        <Label Text="Macoratti .net"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            TextColor="{StaticResource labelTextColor}"
            FontSize="{StaticResource labelFontSize}"
            />
        <Label Text="Quase tudo para .NET"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            TextColor="{StaticResource labelTextColor}"
            FontSize="{StaticResource labelFontSize}"
            />
        <Button Text="Exemplo de uso"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            BorderWidth="{StaticResource buttonBorderWidth}"
            FontSize="{StaticResource buttonFontSize}"
            TextColor="{StaticResource buttonTextColor}"
            />
        <Button Text="de ResourceDictionary"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand"
            BorderWidth="{StaticResource buttonBorderWidth}"
            FontSize="{StaticResource buttonFontSize}"
            TextColor="{StaticResource buttonTextColor}"
            />
    </StackLayout>
</ContentPage>

Note que estamos acessando os recursos usando a marcação {StaticResource nome_do_recurso_definido}.

O recurso StaticResource ajuda na manutenção do código mas é um recurso estático que é usado quando a aplicação é carregada não sendo passível de alteração com a aplicação em execução.

Para poder alterar os valores em tempo de execução, sob demanda, temos que usar os Dynamic Resources que veremos na próxima parte do artigo.

Pegue o código da página usada neste artigo::    App_ResourceDictionary.zip  (sem as referências)

Aquele que nem mesmo a seu próprio Filho poupou, antes o entregou por todos nós, como nos não dará também com ele todas as coisas?
Romanos 8:32



Referências:


José Carlos Macoratti