Xamarin.Forms controls with Effects

Xamarin.Forms renders user interface natively on each platform using a renderer class that creates the corresponding native control for that platform. For more details about How Renderer works and customize a control refer this link. By using custom renderer, you can easily customize the appearance or behavior of a control. You can even create entirely new controls by defining a shared interface in Xamarin.Forms and create custom renderers to render the control on each platform natively. This approach is perfect when heavy platform-specific customizations is needed.

Xamarin.Forms 2.2 introduces a new feature named Effects that greatly simplifies this process, allowing native controls on each platform to be more easily customized.

In this blog post, you will learn how to create your own custom effect and i will share the code of the TintEffect which i created during my recent development for the Image control in Xamarin.Forms.

Introduction to Effects

Effects allow the native controls on each platform to be customized without having to implement a custom renderer. They simplify the customization of a native control and are typically used for small styling changes. Anything that can be achieved with an effect can also be achieved with a custom renderer. However, custom renderers offer more flexibility and customizations. Refer to xamarin API guidelines which approach is needed for your customization.

effects-diagram

First we need to create an effect by subclassing the RoutingEffect  in the PCL project for ex:

public class TintEffect : RoutingEffect
{
    public Color TintColor { get; set; }
    public TintEffect () : 
           base ("EffectsSample.TintEffect")
    {
    }
}

“EffectsSample” -> ResolutionGroupName which is discussed below.

Now to consume the effect in NativePlatforms we need to create an effect by subclassing the PlatformEffect in the native platforms for which we need customization.

For Xamarin.Forms to discover the effects created in the platform-specific projects,           we need to add ResolutionGroupNameand ExportEffect attributes.

  • Add a ResolutionGroupName attribute to the custom effect class. This attribute ensures the effects are created inside a unique namespace preventing collisions with other effects with the same name. Please note, this attribute can be applied only once per project. In the sample project you will see them specified only once in the TintEffectclass
  • Add an ExportEffect attribute to the custom effect class. This attribute registers the effect with a unique ID that’s used by Xamarin.Forms, along with the group name, to locate the effect prior to applying it to a control. The attribute takes two parameters: the type name of the effect and a unique string that will be used to locate the effect prior to applying it to a control.
[assembly:ResolutionGroupName ("EffectsSample")]
[assembly:ExportEffect (typeof(TintEffect), "TintEffect")]
namespace EffectsSample.Droid
{
    public class TintEffect : PlatformEffect
    {

Each platform-specific PlatformEffect class exposes the following methods, which must be overridden to implement an effect:

  • OnAttached – called when an affect is attached to a Xamarin.Forms control. An overridden version of this method, in each platfom-specific effect class, is the place to perform customization of the control, along with exception handling in case the effect cannot be applied to the specified Xamarin.Forms control.
  • OnDetached – called when an effect is detached from a Xamarin.Forms control. An overridden version of this method, in each platform-specific effect class, is the place to perform any effect cleanup such as de-registering an event handler.

Customize the controls by attaching it to appropriate the Xamarin.forms controls

protected override void OnAttached ()
{
   var imageView = Control as ImageView;
   var tintEffect = (TintEffect) Element.Effects.FirstOrDefault(row => row is 
                     TintEffect);
   imageView.SetColorFilter(tintEffect.TintColor.ToAndroid());
}  
protected override void OnDetached ()
{ 
  // UnHook any events or reset the control back to the state.
}

Consume the Effect in Xamarin.Forms

Effects are consumed by first defining the control in Xamarin.Forms and then adding the custom effect to its Effects Collection.

<Image Grid.Column="1" Source="ic_share.png">
   <Image.Effects>
      <effects:TintEffect TintColor="#4CAF50"/>
    </Image.Effects>
</Image>

Nexus 5 (Lollipop) Screenshot 5
Share-icon with Green TintEffect

Summary

Effects are a useful feature since they allow the native controls on each platform to be customized without having to implement a custom renderer for simple and small styling changes. In the above case i have configured Effects with passing CLR properties it be further empowered for reusability by using attached properties. For more information, visit xamarin documentation on passing attached properties parameters to an effect.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s