¿Qué son los Xamarin effects?

fernando-avatar-200px.png

Escrito por
Mobile Developer 27 julio, 2017

Los Effectsnos permiten controlar la apariencia de los elementos en las distintas plataformas, son perfectos para pequeños cambios de estilo. 

¿Effects o CustomRenders?

Los Effects son simples, reusables y pueden recibir parámetros. 

Cualquier cosa que se pueda hacer con Effects también puede hacerse con un Custom Renderer. Estos últimos son mucho más complejos y potentes, y por tanto, los Effects son ideales cuando no son necesarias las capacidades de un Custom Renderer, concretamente:

  • Cuando es necesario realizar un subclass o sobreescribir algún método en el control nativo
  • Cuando es necesario reemplazar el control nativo que implementa el control de Xamarin.Forms 

Los Effects son ideales para las tareas en las que simplemente modificando propiedades ya implementadas en el control nativo obtendremos el resultado deseado. 

 

¿Cómo crear un Effect?

El proceso para crear un Effect es el siguiente: 

  1. Crear una clase que herede de PlatformEffect
  2. Sobreescribir los métodos OnAttached y OnDetached
  3. Añadir un atributo "ResolutionGroupName" a la clase: Este atributo genera un namespace para todos los effects, solo puede usarse una vez por proyecto. 
  4. Añadir un atributo "ExportEffect" a la clase: Este atributo toma dos parámetros, el nombre de la clase de Effect y el nombre único que identifica al Effect

Una vez creados, los Effect pueden ser utilizados asignándolos al control apropiado. 

 

Setup del proyecto: 

Crearemos un proyecto base de Xamarin.Forms utilizando el template. 

Añadiremos un control que usaremos para mostrar el Effect al XAML de la página principal: 

<?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="EffectsDemo.HomePage"> 

<StackLayout> 

<Label Text="Effects Demo" FontAttributes="Bold" HorizontalOptions="Center" /> 

        <Entry x:Name="entry" Text="Texto de ejemplo para effects" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"> 

        </Entry> 

</StackLayout> 

</ContentPage> 

Una vez tenemos un control al que aplicar el Effect, lo haremos desde el código asociado al XAML:  

entry.Effects.Add(Effect.Resolve("MyCompany.TextColorEffect")); 

 

Donde entry es el control que hemos definido. "Mycompany" es el namespace al que vamos a asociar los Effects, y "TextColorEffect" es el nombre del Effect que vamos a crear a continuación. 

 

Ejemplo de Effect para Android

Crearemos un Effect sencillo para modificar el color de texto de un TextView: 

[assembly:ResolutionGroupName ("MyCompany")] 

[assemblyExportEffect(typeof(TextColorEffect), "TextColorEffect")] 

namespace EffectsDemo.Droid 

{ 

    public class TextColorEffect : PlatformEffect 

    { 

        protected override void OnAttached() 

        { 

            try 

            { 

                ((TextView)Control).SetTextColor(Android.Graphics.Color.LightGreen); 

            } 

            catch (Exception ex) 

            { 

                Console.WriteLine("Error al aplicar el Effect. Error: "ex.Message); 

            } 

        } 

 

        protected override void OnDetached() 

        { 

 

        } 

    } 

} 

El código es muy sencillo. Siguiendo los pasos generales anteriores hemos creado una clase heredando de PlatformEffect e implementando sus métodos. En OnAttached realizaremos la acción del Effect. En este caso cambiar el color del texto. 

Es importante el bloque try - catch, ya que si asignásemos el Effect a un control que no fuera el esperado se produciría un crash de la app. 

 

effects2.jpg

 

 Ejemplo de Effect para iOS: 

El código de Effect para iOS es exactamente igual con la única diferencia del manejo del control nativo. En este caso, en lugar de TextView se espera un UILabel, por tanto, debemos utilizar los métodos de UILabel para realizar la acción de nuestro Effect: 

[assembly:ResolutionGroupName("MyCompany")] 

[assembly:ExportEffect(typeof(TextColorEffect), "TextColorEffect")] 

 

namespace EffectsDemo.iOS 

{ 

    public class TextColorEffect : PlatformEffect 

    { 

        protected override void OnAttached() 

        { 

            try 

            { 

                ((UILabel)Control).TextColor = UIColor.FromRGB(204, 153, 255); 

            } 

            catch (Exception ex) 

            { 

                Console.WriteLine("Error al aplicar el Effect. Error: "ex.Message); 

            } 

        } 

 

        protected override void OnDetached() 

        { 

 

        } 

    } 

} 

Simulator Screen Shot 20 jul 2017 14.12.48.png

 

Ejemplo de Effects con parámetros:

Hasta ahora los Effects que hemos creado llevaban un color fijado en el código (hardcoded), vamos a modificarlo para que podamos elegir el color que queremos al aplicar el Effect. 

Para conseguirlo, debemos crear un "wrapper" que debe heredar de RoutingEffect para nuestros effects, el cual crearemos en la PCL: 

    public class ColorEffect : RoutingEffect 

    { 

        public Color Color getset; } 

 

        public ColorEffect() : base ("MyCompany.TextColorEffect") 

        { 

 

        } 

    }

Es importante que llamemos al constructor de la clase padre indicándole el nombre completo de nuestro Effect (Namespace.NombreEfecto

A continuación, debemos modificar los Effects en la plataforma para reflejar estos cambios: 

public class TextColorEffect : PlatformEffect 

    { 

        protected override void OnAttached() 

        { 

            try 

            { 

                var effect = (ColorEffect)Element.Effects.FirstOrDefault(e => e is ColorEffect); 

                if (effect !null) 

                { 

                    ((TextView)Control).SetTextColor(Android.Graphics.Color.Rgb((int)effect.Color.R, (int)effect.Color.G, (int)effect.Color.B)); 

                } 

            } 

            catch (Exception ex) 

            { 

                Console.WriteLine("Error al aplicar el Effect. Error: "ex.Message); 

            } 

        }

En resumen, obtendremos la instancia del "RoutingEffect" que hemos creado anteriormente, y de él obtendremos los parámetros que hemos indicado al llamarlo. 

Para utilizarlo crearemos una instancia de nuestro wrapper y le asignamos el color, lo añadiremos como si fuera un Effect normal sin parámetros. 

  entry.Effects.Add(new ColorEffect { Color = Color.Green });

¡Y con esto ya tenemos funcionando nuestro Effect con parámetros! 

Espero que os haya gustado este post y que os animéis a probar los XamarinEffects. 

¡Hasta otra! 

ojo_07 ¿ Te gusta lo que lees? Suscríbete a nuestras newsletters