[Tips and Tricks] Librería para reutilizar estilos entre diferentes Apps Xamarin.Forms

Introducción

En toda aplicación móvil la apariencia visual es vital. Cada vez es mayor el esfuerzo depositado a la hora de crear aplicaciones atractivas a la par que intuitivas y en muchos casos conseguir una imagen única que diferencia a la Aplicación del resto es prioritario. Por este motivo, debemos de contar con opciones sencillas de poder personalizar los distintos elementos que componen la interfaz.

Los estilos permitir definir múltiples propiedades visuales de elementos de la interfaz de forma reutilizable.

En ocasiones, se desarrollan diferentes aplicaciones para la misma empresa o marca comercial. Hablamos de aplicaciones totalmente diferentes pero que sin duda, van a compartir algunos elementos visuales específicos como colores, logos e incluso algunos estilos visuales (forma de botones, etc.).

¿Cómo lograr reutilizar estilos entre diferentes aplicaciones Xamarin.Forms?

ResourceDictionary

Los recursos XAML son objetos que podemos reutilizar más de una vez. Hablamos desde un sencillo color o tamaño de fuente, a el uso de estilos. Los diccionarios de recursos o ResourceDictionaries permiten definir una zona donde definir recursos.

Podemos definir recursos a nivel de elemento visual, a nivel de página e incluso a nivel de Aplicación.

¿Cómo definimos recursos en otra librería?.

Buscamos tener una librería con recursos, estilos y/o converters que sea compartida entre diferentes aplicaciones:

Librería

  • Aplicación 1
  • Aplicación 2

Creando una librería

Comenzamos creando una librería portable (PCL). En Visual Studio, nuevo proyecto de tipo PCL:

PCL

Añadimos el paquete NuGet de Xamarin.Forms. Y a continuación, añadimos una página de tipo ContentPage:

ContentPage

Renombramos ContentPage por ResourceDictionary en la página recien creada.

Todo listo!.

Bastará con añadir recursos, estilos o converters. Ejemplo:

<Style x:Key="SharedButtonStyle" TargetType="Button">
     <Setter Property="BackgroundColor" Value="Red" />
     <Setter Property="Rotation" Value="45" />
</Style>

Utilizando la librería

Para utilizar la librería desde una aplicación Xamarin.Forms, comenzamos añadiendo la referencia a la librería desde la aplicación:

Referencias

Añadida la referencia, llega el paso de mayor importancia. A nivel de Aplicación, tenemos la posibilidad de añadir recursos en un diccionario de recursos:

<Application.Resources>
     <ResourceDictionary>

     </ResourceDictionary>
</Application.Resources>

Vamos a utilizar la propiedad MergedWith para añadir a los estilos de la aplicación, los estilos de la librería:

<Application
     xmlns:styles="clr-namespace:Styles;assembly=Styles">
    <Application.Resources>
        <ResourceDictionary MergedWith="styles:ButtonStyles">

        </ResourceDictionary>
    </Application.Resources>
</Application>

El resultado:

Estilos desde otra librería!

Realizamos una combinación de estilos a nivel de elemento visual, página, Aplicación e incluso desde otra librería (último botón). Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHubRecuerda, cualquier tipo de duda o sugerencia es bienvenida en los comentario del artículo.

Más información

[Xamarin.Forms] Novedades de la versión 1.3: Estilos

Xamarin LogoNovedades de Xamarin.Forms 1.3

Recientemente Xamarin lanzo la version 1.3 definitiva de Xamarin.Forms con una cantidad de novedades muy sustansiosa. Entre otras novedades contamos con:

  • Soporte para Estilos.
  • Soporte para Behaviors.
  • Soporte para Triggers (DatTriggers y MultiTriggers).
  • Nuevo miembro en las páginas, OnBackButtonPressed para gestionar la pulsación del botón físico atrás.
  • Mejoras en el DependencyService para añadir más flexibilidad a la hora de registrar dependencias.
  • Corrección de bugs.

Del listado podemos sacar varias opciones muy interesantes entre las que destaca el uso de estilos. En este artículo vamos a analizar todas las novedades relacionadas con el uso de estilos en Xamarin.Forms 1.3.

¿Te apuntas?

Estilos

En toda aplicación móvil la apariencia visual es vital. Cada vez es mayor el esfuerzo depositado a la hora de crear aplicaciones atractivas a la par que intuitivas y en muchos casos conseguir una imagen única que diferencia a la Aplicación del resto es prioritario. Por este motivo, debemos de contar con opciones sencillas de poder personalizar los distintos elementos que componen la interfaz.

Los estilos permitir definir múltiples propiedades visuales de elementos de la interfaz de forma reutilizable.

Para analizar todas las novedades en estilos incluidas en Xamarin.Forms 1.3 vamos a crear un nuevo proyecto desde cero:

Nuevo proyecto Xamarin Forms

Nuevo proyecto Xamarin Forms

Tras crear el proyecto procedemos a actualizar a Xamarin.Forms 1.3. Para ello, vamos a gestionar los paquetes NuGet a nivel de solución.

NuGet Xamarin.Forms 1.3

NuGet Xamarin.Forms 1.3

NOTA: Si tenéis problemas al instalar Xamarin. 1.3 aseguráos de contar con la última versión de NuGet. Versiones antiguas de NuGet pueden ocasionar problemas en la instalación. Para asegurar tener la última versión debemos dirigirnos a Herramientas > Extensiones y Actualizaciones -> Instalados. Aqui podremos seleccionar NuGet e instalar la última versión.

Utilizaremos elementos simples para aprender a utilizar controles, en este ejemplo, botones. Podemos modificar la apariencia del control estableciendo directamente propiedades en el control:

<Button
     TextColor="Yellow"
     Text="Sin Estilo" />

El resultado:

Apariencia de nuestro botón

Apariencia de nuestro botón

Realmente es algo bastante sencillo, pero… ¿qué ocurriría si tuviesemos múltiples botones en la Aplicación que deben tener la misma apariencia visual?.

No suena muy óptimo repetir la misma asignación de propiedades una y otra vez, ¿cierto?. En estos casos lo ideal es utilizar estilos. Podemos definir un estilo directamente en un elemento visual:

<Button
     Text="Estilo como recurso del botón">
     <Button.Style>
        <Style TargetType="Button">
          <Setter Property="TextColor" Value="Blue" />
        </Style>
     </Button.Style>
</Button>
Estilo aplicado al botón

Estilo aplicado al botón

El estilo se define con propiedades Setter. Cada propiedad establecidad de tipo Setter puede modificar el valor de una propiedad del elemento indicado en TargetType. Eastablecemos la propiedad en Property y el valor en Value. En nuestro pequeño ejemplo, contamos con un Setter que modifica la propiedad TextColor del elemento de tipo Button.

Continuamos. Si tuviesemos múltiples botones y quisieramos aplicar el mismo estilo, de la forma anterior no logramos reutilizar código. Podemos reutilizar estilos de manera muy simple. Todas las páginas tienen una propiedad Resources. Esta propiedad es de tipo ResourceDictionary, permitiendo contener un diccionario de claves de tipo string y de valor de tipo object.

<ContentPage.Resources>
</ContentPage.Resources>

El estilo definido en los recursos de la página:

<Style x:Key="ButtonStyle" TargetType="Button">
     <Setter Property="HorizontalOptions" Value="Center" />
     <Setter Property="VerticalOptions" Value="Center" />
     <Setter Property="TextColor" Value="Green" />
</Style>

Definimos el estilo como hemos visto previamente con un conjunto n de Setters. Es importante recalcar que establecemos la propiedad Key que nos permite establecer una clave al estilo para poder referenciar al mismo en cualquier elemento de manera fácil y sencilla. Este tipo de estilos reciben el nombre de estilos explícitos.

Definimos un botón y utilizamos su propiedad Style para acceder al estilo definido.

<Button
     Text="Estilo Explícito"
     Style="{StaticResource ButtonStyle}"/>
<Button
Estilo Explícito

Estilo Explícito

De esta forma podemos definir un conjunto de propiedades en un estilo y en los elementos deseados acceder al mismo. Sin  embargo, si queremos aplicar el mismo estilo a todos los botones no es necesario definir la propiedad Key en el estilo.

<Style TargetType="Button">
     <Setter Property="HorizontalOptions" Value="Center" />
     <Setter Property="VerticalOptions" Value="Center" />
     <Setter Property="TextColor" Value="Red" />
</Style>

Definimos el estilo exactamente igual pero sin propiedad Key. Este estilo recibe el nombre de estilo implícito. Si añadimos botones en la vista:

<Button
     Text="Estilo Implícito" />
Estilo Implícito

Estilo Implícito

Automáticamente sin realizar ninguna acción extra, el estilo implícito se aplica al botón.

NOTA: Importante recordar que si aplicamos una propiedad directamente en un elemento visual, si valor tiene prioridad sobre cualquier otro estilo explícito o implícito.

Estilos heredados

Otra de las características fundamentales que tenemos disponible en Xamarin.Forms 1.3 con los estilos es la herencia de estilos. De esta forma, podemos extender un estilo base añadiendo más opciones o incluso sobreescribiendo algunas de las propiedades establecidas.

Recordamos el estilo utilizado hasta ahora:

<Style TargetType="Button">
     <Setter Property="HorizontalOptions" Value="Center" />
     <Setter Property="VerticalOptions" Value="Center" />
     <Setter Property="TextColor" Value="Red" />
</Style>

Podemos crear un estilo basado en otro utilizando la propiedad BasedOn:

<Style x:Key="InheritedButtonStyle" TargetType="Button" BasedOn="{StaticResource ButtonStyle}">
     <Setter Property="BorderColor" Value="Green" />
     <Setter Property="FontSize" Value="Large" />
</Style>

El estilo anterior define los valores para las propiedades BorderColor y FontSize además de incluir las definiciones de ButtonStyle.

<Button
     Text="Herencia de Estilos"
     Style="{StaticResource InheritedButtonStyle}" />

El resultado:

Herencia de estilos

Herencia de estilos

One more thing…

Nos queda por ver otra posibilidad muy habitual e interesante, definir estilos a nivel de aplicación. En Xamarin.Forms contamos con una nueva clase base Application.

Podemos definir una página con XAML y su code behind asociado definiendo la Aplicación:

<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"                    
x:Class="Xamarin_Styles.App">
 
</Application>

La clase deriva de Application:

public partial class App : Application
{
     public App()
     {
         InitializeComponent();
         MainPage = new NavigationPage(new MainView());
     }
}

Podemos definir recursos a nivel de Aplicación donde crear desde recursos a estilos más complejos a compartir a lo largo de toda la aplicación:

<Application.Resources>  
     <ResourceDictionary>
          <Style
               x:Key="AppButtonStyle"
               TargetType="Button">
               <Setter Property="Rotation" Value="25" />
          </Style>
     </ResourceDictionary>
</Application.Resources>

En nuestra vista principal podemos acceder al estilo definido en App.xaml:

<Style x:Key="InheritedAppButtonStyle" TargetType="Button" BasedOn="{StaticResource AppButtonStyle}">
     <Setter Property="BorderColor" Value="Green" />
     <Setter Property="FontSize" Value="Large" />
</Style>

El botón:

<Button
     Text="Herencia de Estilos desde App"
     Style="{StaticResource InheritedAppButtonStyle}"/>

El resultado final:

Estilos definidos en App

Estilos definidos en App

Podéis descargar el ejemplo completo realizado a continuación:

También tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordar que podéis dejar en los comentarios cualquier tipo de sugerencia o pregunta.

Más información

[Tips and Tricks] Temas personalizados en Windows Phone

Accent-ColorsIntroducción

Al crear aplicaciones, un punto importante en el proceso creativo es la elección de colores y estilos de la misma. En determinadas ocasiones estaremos creando algo nuevo y la selección será bajo nuestro criterio mientras que en otras ocasiones estaremos realizando una aplicación para una marca ya establecida en cuyo caso debemos crear una aplicación que se adapte al esquema de colores ya seleccionados por la marca.

Problema

Si por marca decidimos que los colores adecuados para nuestra aplicación siempre serán el naranja junto al fondo claro por ejemplo, puede ser que no siempre el usuario obtenga el resultado que nosotros esperamos. El usuario puede cambiar el tema del sistema afectando a fondos, bordes y colores de fuentes de múltiples controles y por lo tanto a nuestra aplicación.

¿Solución?

Como suele ser habitual tenemos varias opciones para resolver el problema. La primera de ellas consiste en crearnos un conjunto de estilos sobreescribiendo los establecidos por defecto. Podemos dirigirnos a la ruta:

C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Design

Seleccionamos el tema Light o Dark según se adapte más a nuestras necesidades y partiendo de esa base crear nuestro propio estilo que añadiremos como recurso. Esta solución aunque válida requiere un esfuerzo elevado.

Tenemos una segunda opción que nos permite resolver en problema con un par de líneas. Interesante, ¿verdad?.

Utilizaremos para ello una librería creada por Jeff Wilcox llamada Windows Phone Theme Manager. Tenéis la librería disponible como paquete NuGet y también acceso al código fuente desde GitHub.

Ya sea obteniendo el paquete desde NuGet o desde GitHub, su uso es simple, en el constructor de la aplicación:

/// <summary>
/// Constructor.
/// </summary>
public App()
{
     // Global handler for uncaught exceptions.
     UnhandledException += Application_UnhandledException;

     // Standard Silverlight initialization
     InitializeComponent();

     // Phone-specific initialization
     InitializePhoneApplication();

     //More code here...
}

Añadiremos la siguiente línea para forzar el tema claro:

ThemeManager.ToLightTheme();

O el tema oscuro:

ThemeManager.ToDarkTheme();

NOTA: Si forzamos un tema ha de hacerse una única vez y desde el constructor de App.cs tras las llamadas de inicialización.

O incluso podemos utilizar temas personalizados con suma facilidad. Añadimos un conjunto de recursos (ThemeResource.xaml) con todos los estilos personalizados que necesitemos al proyecto. Para tener acceso  los recursos, en App.xaml los añadimos al MergeDictionary. Una vez realizado, utilizarlo sería tan sencillo como:

// Obtenemos el tema
var rd = App.Current.Resources.MergedDictionaries.First();

// Establecemos el tema
ThemeManager.SetCustomTheme(rd, Theme.Light);

De esta forma tan simple podemos forzar a nuestra aplicación a utilizar siempre el tema claro o el oscuro. O incluso utilizar un conjunto de estilos junto al tema claro u oscuro.

Más información