Gradient Pages in Xamarin.Forms

Special thanks to the Xamarin community from which this post is based on: https://forums.xamarin.com/discussion/22440/gradient-as-background-color

Gradient Pages in Xamarin Forms

The objective is to have a page with a background color that transitions from one to another.

Show me the code!

First, create a simple page class that inherits from ContentPage:

public class GradientContentPageContentPage
{
    public Xamarin.Forms.Color StartColor { getset; }
    public Xamarin.Forms.Color EndColor { getset; }
}

You’re going to need a renderer in both Android and iOS which will draw the gradient on the GradientContentPage:

iOS:

[assemblyExportRenderer(typeof(GradientContentPage), typeof(GradientContentPageRenderer))]
namespace MyApp.iOS
{
    public class GradientContentPageRenderer : PageRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != nullreturn;
            if (e.NewElement is GradientContentPage page)
            {
                var gradientLayer = new CAGradientLayer
                {
                    Frame = View.Bounds,
                    Colors = new CGColor[] {page.StartColor.ToCGColor(), page.EndColor.ToCGColor()}
                };
                View.Layer.InsertSublayer(gradientLayer, 0);
            }
        }
    }
}

And Android:

[assemblyExportRenderer(typeof(GradientContentPage), typeof(GradientContentPageRenderer))]
namespace MyApp.Droid
{
    public class GradientContentPageRenderer : PageRenderer
    {
        public GradientContentPageRenderer(Context context) : base(context)
        {
        }
 
        private Xamarin.Forms.Color StartColor { getset; }
        private Xamarin.Forms.Color EndColor { getset; }
        protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
        {
            var gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height,
                this.StartColor.ToAndroid(),
                this.EndColor.ToAndroid(),
                Android.Graphics.Shader.TileMode.Mirror);
            var paint = new Android.Graphics.Paint()
            {
                Dither = true,
            };
            paint.SetShader(gradient);
            canvas.DrawPaint(paint);
            base.DispatchDraw(canvas);
        }
 
        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);
 
            if (e.OldElement != null || Element == null)
            {
                return;
            }
 
            try
            {
                var page = e.NewElement as GradientContentPage;
                this.StartColor = page.StartColor;
                this.EndColor = page.EndColor;
            }
            catch (Exception ex)
            {
               //Publish the error
            }
        }
 
    }
}

Now that we have the renderers ready, add a new XAML page and base it on GradientContentPage:

public partial class LoginPage : GradientContentPage

In the XAML, you need to tell the XAML that the page is based on the custom page, not the standard page. Notice the xmlns:page code:

<page:GradientContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:page="clr-namespace:MyApp.Views.Common;assembly=MyApp"
             x:Class="MyApp.LoginPage"
             StartColor="DarkBlue"
             EndColor="LightBlue">

That’s it!

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