Customizing Xamarin.Forms Controls with Effects

Nish Anil

            Xamarin.Forms allows you to build native user interfaces for iOS, Android, and Windows from a single shared codebase using C# or XAML. Each user interface element in Xamarin.Forms is rendered natively on each platform using a renderer class that creates the corresponding native control for that platform. For example, the Xamarin.Forms control <code>Entry</code> is rendered as a <code>UITextField</code> on iOS, an <code>EditText</code> on Android, and a <code>TextBox</code> on Windows. By extending the existing renderer for a control, 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 for heavy platform-specific customizations.

What if you would like to perform a simple control customization? Creating a custom renderer sometimes can be a heavyweight response. Xamarin.Forms 2.1 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 for the Slider 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 our guidelines on which approach is right for your customization.

Showing off Xamarin.Forms 2.1's new feature named effects with the Slider control.

Getting Started

Effects are written in platform-specific projects and are consumed in shared or PCL projects in Xamarin.Forms. Creating an effect involves two simple steps:

  1. Create an effect by subclassing PlatformEffect in the native platform you wish to customize.
  2. Consume the effect by attaching it to the appropriate Xamarin.Forms control.

Diagram explaining how effects work in relation to each platform and Xamarin.Forms.

Creating an Effect

Effects are created in the platform-specific project. First, create a custom class that inherits from PlatformEffect and override the OnAttached and OnDetached methods.

  • OnAttached: called when an effect is attached to a Xamarin.Forms control. Use this method 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. Use this method to perform any effect cleanup, such as resetting to an older value or de-registering an event handler.

Applying the Customization for iOS

Subclass the PlatformEffect class and override the OnAttached method.

public class RedSliderEffect : PlatformEffect
{
    protected override void OnAttached()
    {
        var slider = (UISlider)Control;
        slider.ThumbTintColor = UIColor.FromRGB(255, 0, 0);
        slider.MinimumTrackTintColor = UIColor.FromRGB(255, 120, 120);
        slider.MaximumTrackTintColor = UIColor.FromRGB(255, 14, 14);
    }

    protected override void OnDetached()
    {
        // Use this method if you wish to reset the control to original state
    }
}

Applying the Customization for Android

Subclass the PlatformEffect class in your Android project and write the customizations in the OnAttached method.

public class RedSliderEffect : PlatformEffect
{
    protected override void OnAttached()
    {
        var seekBar = (SeekBar)Control;
        seekBar.ProgressDrawable.SetColorFilter(new PorterDuffColorFilter(Xamarin.Forms.Color.Red.ToAndroid(), PorterDuff.Mode.SrcIn));
        seekBar.Thumb.SetColorFilter(new PorterDuffColorFilter(Xamarin.Forms.Color.Red.ToAndroid(), PorterDuff.Mode.SrcIn));
    }

    protected override void OnDetached()
    {
        // Use this method if you wish to reset the control to original state
    }
}

Setup Attributes

For Xamarin.Forms to discover the effects created in the platform-specific projects, we need to add ResolutionGroupName and 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 RedSliderEffect class.
  • 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(RedSliderEffect), "RedSliderEffect")]
namespace Effects
{
    ...
}

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.

var redSlider = new Slider
{
    Minimum = 0,
    Maximum = 100,
    Value = 80
};

var content = new ContentPage
{
    Title = "Effects",
    Content = new StackLayout
    {
        VerticalOptions = LayoutOptions.Start,
        Children = {
            redSlider
        }
    }
};

redSlider.Effects.Add(Effect.Resolve("EffectsSample.RedSliderEffect"));

The RedSliderEffect is attached to the Slider instance by adding the effect to the control’s Effects Collection. The Effect.Resolve method returns an effect for the specified name, which is a concatenation of the values specified in the ResolutionGroupName and the ExportEffect attributes on the effect class.

Xamarin.Forms-Effects-Android

 

Wrapping Up

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. Effects can be further empowered for reusability by using parameters. For more information, visit our documentation on passing parameters to an effect. For a hands-on look at effects, be sure to download the slider sample used in this blog post.

0 comments

Discussion is closed.

Feedback usabilla icon