'Add Gradient background to layouts in Xamarin Forms visual studio

I am a newbie in Xamarin Forms, I create a ContentPage for Menu. I need linear gradient color at its background. But I can't find any link which tell me how to create background gradient color. I also want that color place at button background like selector in android. If you have any information please give reply.



Solution 1:[1]

In below code we can set Horizontal and Vertical Gradient(I put it in #region) for any Layout in below I write for StackLayout if you want to write another Layout just replace your Layout on StackLayout.

In PCL:

using System;
using Xamarin.Forms;

namespace GradientColor
 {
   public class GradientColorStack : StackLayout
    {
      public Color StartColor { get; set; }
      public Color EndColor { get; set; }
    }
 }

Xamarin.Android:

  using System;
  using GradientColor;
  using GradientColor.Droid;
  using Xamarin.Forms;
  using Xamarin.Forms.Platform.Android;
  [assembly: ExportRenderer(typeof(GradientColorStack), typeof(GradientColorStackRenderer))]

 namespace GradientColor.Droid
  {
     public class GradientColorStackRenderer : VisualElementRenderer<StackLayout>
       {
    private Color StartColor { get; set; }
    private Color EndColor { get; set; }

    protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
      {
        #region for Vertical Gradient
        //var gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height,
        #endregion

        #region for Horizontal Gradient
     var gradient = new Android.Graphics.LinearGradient(0, 0, Width, 0,
          #endregion

            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<StackLayout> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null || Element == null)
        {
            return;
        }
        try
        {
            var stack = e.NewElement as GradientColorStack;
            this.StartColor = stack.StartColor;
            this.EndColor = stack.EndColor;
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
        }
      }
   }
}

Xamarin.iOS:

  using System;
  using CoreAnimation;
  using CoreGraphics;
  using GradientColor;
  using GradientColor.iOS;
  using Xamarin.Forms;
  using Xamarin.Forms.Platform.iOS;
  [assembly: ExportRenderer(typeof(GradientColorStack), typeof(GradientColorStackRenderer))]

 namespace GradientColor.iOS
   {
public class GradientColorStackRenderer : VisualElementRenderer<StackLayout>
    {
      public override void Draw(CGRect rect)
      {
        base.Draw(rect);
        GradientColorStack stack = (GradientColorStack)this.Element;
        CGColor startColor = stack.StartColor.ToCGColor();

        CGColor endColor = stack.EndColor.ToCGColor();

        #region for Vertical Gradient

        var gradientLayer = new CAGradientLayer();

        #endregion

        #region for Horizontal Gradient

        //var gradientLayer = new CAGradientLayer()
        //{
        //  StartPoint = new CGPoint(0, 0.5),
        //  EndPoint = new CGPoint(1, 0.5)
        //};

        #endregion



        gradientLayer.Frame = rect;
        gradientLayer.Colors = new CGColor[] { startColor, endColor 
        };

        NativeView.Layer.InsertSublayer(gradientLayer, 0);
      }
    }
 }

In XAML:

 <?xml version="1.0" encoding="utf-8"?>
 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:GradientColor; assembly:GradientColor" x:Class="GradientColor.GradientColorPage">
 <Grid VerticalOptions="FillAndExpand" RowSpacing="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0" BackgroundColor="Olive">
         <StackLayout VerticalOptions="Center">
            <Label Text="Normal color for stacklayout" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"  TextColor="White"/>
         </StackLayout>
    </Grid>
    <Grid Grid.Row="1">
         <local:GradientColorStack StartColor="Green" EndColor="Red">
               <StackLayout VerticalOptions="CenterAndExpand">
               <Label Text="Gradient color for StackLayout" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"   TextColor="White"/>
               </StackLayout>

         </local:GradientColorStack>
     </Grid>
   </Grid>
  </ContentPage>

Solution 2:[2]

For those who want a full featured gradient in Xamarin.Forms apps, there is my code:

In your PCL

GradientLayout.cs

using Xamarin.Forms;

namespace MyProject.Renderers
{
    public class GradientLayout : StackLayout
    {
        public string ColorsList { get; set; }
      
        public Color[] Colors
        {
            get
            {
                string[] hex = ColorsList.Split(',');
                Color[] colors = new Color[hex.Length];

                for (int i = 0; i < hex.Length; i++)
                {
                    colors[i] = Color.FromHex(hex[i].Trim());
                }

                return colors;
            }
        }

        public GradientColorStackMode Mode { get; set; }
    }
}

GradientColorStackMode.cs

namespace MyProject.Renderers
{
    public enum GradientColorStackMode
    {
        ToRight,
        ToLeft,
        ToTop,
        ToBottom,
        ToTopLeft,
        ToTopRight,
        ToBottomLeft,
        ToBottomRight
    }
}

In your iOS project

GradientLayoutRenderer.cs

using CoreAnimation;
using CoreGraphics;
using MyProject.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(GradientLayout), typeof(GradientLayoutRenderer))]

namespace MyProject.iOS.Renderers
{
    public class GradientLayoutRenderer : VisualElementRenderer<StackLayout>
    {
        public override void Draw(CGRect rect)
        {
            base.Draw(rect);
            GradientLayout layout = (GradientLayout)Element;

            CGColor[] colors = new CGColor[layout.Colors.Length];

            for (int i = 0, l = colors.Length; i < l; i++)
            {
                colors[i] = layout.Colors[i].ToCGColor();
            }

            var gradientLayer = new CAGradientLayer();

            switch (layout.Mode)
            {
                default:
                case GradientColorStackMode.ToRight:
                    gradientLayer.StartPoint = new CGPoint(0, 0.5);
                    gradientLayer.EndPoint = new CGPoint(1, 0.5);
                    break;
                case GradientColorStackMode.ToLeft:
                    gradientLayer.StartPoint = new CGPoint(1, 0.5);
                    gradientLayer.EndPoint = new CGPoint(0, 0.5);
                    break;
                case GradientColorStackMode.ToTop:
                    gradientLayer.StartPoint = new CGPoint(0.5, 1);
                    gradientLayer.EndPoint = new CGPoint(0.5, 0);
                    break;
                case GradientColorStackMode.ToBottom:
                    gradientLayer.StartPoint = new CGPoint(0.5, 0);
                    gradientLayer.EndPoint = new CGPoint(0.5, 1);
                    break;
                case GradientColorStackMode.ToTopLeft:
                    gradientLayer.StartPoint = new CGPoint(1, 1);
                    gradientLayer.EndPoint = new CGPoint(0, 0);
                    break;
                case GradientColorStackMode.ToTopRight:
                    gradientLayer.StartPoint = new CGPoint(0, 1);
                    gradientLayer.EndPoint = new CGPoint(1, 0);
                    break;
                case GradientColorStackMode.ToBottomLeft:
                    gradientLayer.StartPoint = new CGPoint(1, 0);
                    gradientLayer.EndPoint = new CGPoint(0, 1);
                    break;
                case GradientColorStackMode.ToBottomRight:
                    gradientLayer.StartPoint = new CGPoint(0, 0);
                    gradientLayer.EndPoint = new CGPoint(1, 1);
                    break;
            }

            gradientLayer.Frame = rect;
            gradientLayer.Colors = colors;

            NativeView.Layer.InsertSublayer(gradientLayer, 0);
        }
    }
}

In your Android Project

GradientLayoutRenderer.cs

using System;
using Android.Content;
using MyProject.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(GradientLayout), typeof(GradientLayoutRenderer))]

namespace MyProject.Droid.Renderers
{
    public class GradientLayoutRenderer : VisualElementRenderer<StackLayout>
    {
        private Color[] Colors { get; set; }

        private GradientColorStackMode Mode { get; set; }

        public GradientLayoutRenderer(Context ctx) : base(ctx)
        { }

        protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
        {
            Android.Graphics.LinearGradient gradient;

            int[] colors = new int[Colors.Length];

            for (int i = 0, l = Colors.Length; i < l; i++)
            {
                colors[i] = Colors[i].ToAndroid().ToArgb();
            }

            switch (Mode)
            {
                default:
                case GradientColorStackMode.ToRight:
                    gradient = new Android.Graphics.LinearGradient(0, 0, Width, 0, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToLeft:
                    gradient = new Android.Graphics.LinearGradient(Width, 0, 0, 0, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToTop:
                    gradient = new Android.Graphics.LinearGradient(0, Height, 0, 0, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToBottom:
                   gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToTopLeft:
                    gradient = new Android.Graphics.LinearGradient(Width, Height, 0, 0, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToTopRight:
                    gradient = new Android.Graphics.LinearGradient(0, Height, Width, 0, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToBottomLeft:
                    gradient = new Android.Graphics.LinearGradient(Width, 0, 0, Height, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
                case GradientColorStackMode.ToBottomRight:
                    gradient = new Android.Graphics.LinearGradient(0, 0, Width, Height, colors, null, Android.Graphics.Shader.TileMode.Mirror);
                    break;
            }

            var paint = new Android.Graphics.Paint()
            {
                Dither = true,
            };

            paint.SetShader(gradient);
            canvas.DrawPaint(paint);

            base.DispatchDraw(canvas);
        }

        protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
                return;

            try
            {
                if (e.NewElement is GradientLayout layout)
                {
                    Colors = layout.Colors;
                    Mode = layout.Mode;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
            }
        }
    }
}

In UWP project

GradientLayoutRenderer.cs

using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using MyProject.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using Point = Windows.Foundation.Point;

[assembly: ExportRenderer(typeof(GradientLayout), typeof(GradientLayoutRenderer))]

namespace MyProject.UWP.Renderers
{
    public class GradientLayoutRenderer : VisualElementRenderer<StackLayout, Panel>
    {
        private Color[] Colors { get; set; }

        private GradientColorStackMode Mode { get; set; }

        protected override void UpdateBackgroundColor()
        {
            base.UpdateBackgroundColor();

            LinearGradientBrush gradient;

            GradientStopCollection stopCollection = new GradientStopCollection();

            for (int i = 0, l = Colors.Length; i < l; i++)
            {
                stopCollection.Add(new GradientStop
                {
                    Color = Windows.UI.Color.FromArgb((byte)(Colors[i].A * byte.MaxValue), (byte)(Colors[i].R * byte.MaxValue), (byte)(Colors[i].G * byte.MaxValue), (byte)(Colors[i].B * byte.MaxValue)),
                    Offset = (double)i / Colors.Length
                });
            }

            switch (Mode)
            {
                default:
                case GradientColorStackMode.ToRight:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(0, 0.5),
                        EndPoint = new Point(1, 0.5)
                    };
                    break;
                case GradientColorStackMode.ToLeft:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(1, 0.5),
                        EndPoint = new Point(0, 0.5)
                    };
                    break;
                case GradientColorStackMode.ToTop:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(0.5, 1),
                        EndPoint = new Point(0.5, 0)
                    };
                    break;
                case GradientColorStackMode.ToBottom:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(0.5, 0),
                        EndPoint = new Point(0.5, 1)
                    };
                    break;
                case GradientColorStackMode.ToTopLeft:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(1, 1),
                        EndPoint = new Point(0, 0)
                    };
                    break;
                case GradientColorStackMode.ToTopRight:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(0, 1),
                        EndPoint = new Point(1, 0)
                    };
                    break;
                case GradientColorStackMode.ToBottomLeft:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(1, 0),
                        EndPoint = new Point(0, 1)
                    };
                    break;
                case GradientColorStackMode.ToBottomRight:
                    gradient = new LinearGradientBrush
                    {
                        GradientStops = stopCollection,
                        StartPoint = new Point(0, 0),
                        EndPoint = new Point(1, 1)
                    };
                    break;
            }

            Background = gradient;
        }

        protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
                return;

            try
            {
                if (e.NewElement is GradientLayout stack)
                {
                    Colors = stack.Colors;
                    Mode = stack.Mode;

                    UpdateBackgroundColor();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
            }
        }
    }
}

In your XAML pages

<renderers:GradientLayout
    ColorsList="#dd8f68,#a9a9a9,#3a3939"
    Mode="ToBottomRight">

    <!-- Your content -->

</renderers:GradientLayout>

Hope this will help!

Solution 3:[3]

Add the SkiaSharp Nuget to your project togehter with this class. Use it in your xaml whereever you need a gradient.

public partial class GradientView : ContentView
{
    public Color StartColor { get; set; } = Color.Transparent;
    public Color EndColor { get; set; } = Color.Transparent;
    public bool Horizontal { get; set; } = false;

    public GradientView()
    {
        InitializeComponent();

        SKCanvasView canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
    }

    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        var colors = new SKColor[] { StartColor.ToSKColor(), EndColor.ToSKColor()};
        SKPoint startPoint = new SKPoint(0,0);
        SKPoint endPoint = Horizontal ? new SKPoint(info.Width, 0) : new SKPoint(0, info.Height);

        var shader = SKShader.CreateLinearGradient(startPoint, endPoint, colors, null, SKShaderTileMode.Clamp);

        SKPaint paint = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Shader = shader
        };

        canvas.DrawRect(new SKRect(0, 0, info.Width, info.Height), paint);
    }

Solution 4:[4]

For now there is no real drawing functionality to do that. You may want to set an image as background, you can provide many pictures for the different folders (hdpi, mdpi, xhdpi, etc...) Or you can use custom renderers to extend ContentPage class into your own.

You can take a look at this discussion at Xamarin Forums. https://forums.xamarin.com/discussion/22440/gradient-as-background-color

Solution 5:[5]

First comment ever on SO.

using na2xl answer as an Effect

Effects can be attached to different component, are fully reusable, and don't force you to subclass Forms components.

I added a location system to tune where each color starts and ends in the gradient - 0 absolute beginning / 1 absolute end.

in the NetStandard lib

using System.Linq;
using Xamarin.Forms;

namespace YourProject.Effects
{
    public class GradientEffect : RoutingEffect
    {
        public GradientEffect() : base("YourCompany.GradientEffect")
        {
        }

        public string Colors { get; set; }

        public GradientMode Mode { get; set; }

        public Color[] ColorList => Colors.Split(',').Select(i => Color.FromHex(i.Trim())).ToArray();

        public string Locations { get; set; }

        public float[] LocationList => Locations.Split(',').Select(float.Parse).ToArray();

    }

    public enum GradientMode
    {
        ToRight,
        ToLeft,
        ToTop,
        ToBottom,
        ToTopLeft,
        ToTopRight,
        ToBottomLeft,
        ToBottomRight,
        Null
    }
}

in the iOS project

using System;
using System.Linq;
using CoreAnimation;
using CoreGraphics;
using Foundation;
using YourProject.Effects;
using YourProject.iOS.Effects;
using Serilog;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;


[assembly:ResolutionGroupName ("YourCompany")]
[assembly: ExportEffect(typeof(IosGradientEffect), "GradientEffect")]
namespace YourProject.iOS.Effects
{
    public class IosGradientEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            try
            {
                var nativeView = Control ?? Container;
                var effect = (GradientEffect) Element.Effects.FirstOrDefault(e => e is GradientEffect);
                if (effect == null) return;

                var colors = effect.ColorList.Select(i => i.ToCGColor()).ToArray();

                var gradientLayer = new CAGradientLayer
                {
                    Locations = effect.LocationList?.Select(i => new NSNumber(i)).ToArray()
                };

                switch (effect.Mode)
                {
                    default:
                        gradientLayer.StartPoint = new CGPoint(0, 0.5);
                        gradientLayer.EndPoint = new CGPoint(1, 0.5);
                        break;
                    case GradientMode.ToLeft:
                        gradientLayer.StartPoint = new CGPoint(1, 0.5);
                        gradientLayer.EndPoint = new CGPoint(0, 0.5);
                        break;
                    case GradientMode.ToTop:
                        gradientLayer.StartPoint = new CGPoint(0.5, 1);
                        gradientLayer.EndPoint = new CGPoint(0.5, 0);
                        break;
                    case GradientMode.ToBottom:
                        gradientLayer.StartPoint = new CGPoint(0.5, 0);
                        gradientLayer.EndPoint = new CGPoint(0.5, 1);
                        break;
                    case GradientMode.ToTopLeft:
                        gradientLayer.StartPoint = new CGPoint(1, 1);
                        gradientLayer.EndPoint = new CGPoint(0, 0);
                        break;
                    case GradientMode.ToTopRight:
                        gradientLayer.StartPoint = new CGPoint(0, 1);
                        gradientLayer.EndPoint = new CGPoint(1, 0);
                        break;
                    case GradientMode.ToBottomLeft:
                        gradientLayer.StartPoint = new CGPoint(1, 0);
                        gradientLayer.EndPoint = new CGPoint(0, 1);
                        break;
                    case GradientMode.ToBottomRight:
                        gradientLayer.StartPoint = new CGPoint(0, 0);
                        gradientLayer.EndPoint = new CGPoint(1, 1);
                        break;
                }

                gradientLayer.Frame = nativeView.Bounds;
                gradientLayer.Colors = colors;

                nativeView.Layer.InsertSublayer(gradientLayer, 0);
            }
            catch (Exception ex)
            {
                Log.Fatal(ex.Message);
            }
        }

        protected override void OnDetached()
        {
            Log.Debug("Gradient Effect Detached");
        }
    }
}

** in the Android project**

using System;
using System.Linq;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Graphics.Drawables.Shapes;
using YourProject.Droid.Effects;
using YourProject.Effects;
using Serilog;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly:ResolutionGroupName ("YourCompany")]
[assembly: ExportEffect(typeof(AndroidGradientEffect), "GradientEffect")]
namespace YourProject.Droid.Effects
{
    public class AndroidGradientEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            try
            {
                var effect = (GradientEffect) Element.Effects.FirstOrDefault(e => e is GradientEffect);

                var nativeView = Control ?? Container;

                var colors = effect.ColorList.Select(i => i.ToAndroid().ToArgb()).ToArray();

                var paint = new PaintDrawable();
                paint.Shape = new RectShape();
                paint.SetShaderFactory(new GradientShaderFactory(colors, effect.LocationList, Shader.TileMode.Mirror, effect.Mode));

                nativeView.SetBackgroundDrawable(paint);
            }
            catch (Exception ex)
            {
                Log.Fatal("Couldn't set property for view with effect ex:" + ex.Message);
            }
        }

        protected override void OnDetached()
        {
            Log.Debug("Android Gradient Effect detached");
        }
    }

    internal class GradientShaderFactory : ShapeDrawable.ShaderFactory
    {
        private readonly Shader.TileMode _tileMode;
        private readonly int[] _colors;
        private readonly float[] _locations;
        private readonly GradientMode _gradientMode;


        internal GradientShaderFactory(int[] colors, float[] locations, Shader.TileMode tileMode,
            GradientMode gradientMode)
        {
            _colors = colors;
            _locations = locations;
            _tileMode = tileMode;
            _gradientMode = gradientMode;
        }

        public override Shader Resize(int width, int height)
        {
            LinearGradient gradient;
            switch (_gradientMode)
                {
                    default:
                        gradient = new LinearGradient(0, 0, width, 0, _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToLeft:
                        gradient = new LinearGradient(width, 0, 0, 0, _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToTop:
                        gradient = new LinearGradient(0, height, 0, 0, _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToBottom:
                        gradient = new LinearGradient(0, 0, 0, height, _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToTopLeft:
                        gradient = new LinearGradient(width, height, 0, 0,
                            _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToTopRight:
                        gradient = new LinearGradient(0, height, width,0 ,
                            _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToBottomLeft:
                        gradient = new LinearGradient(width, 0, 0, height,
                            _colors, _locations,
                            _tileMode);
                        break;
                    case GradientMode.ToBottomRight:
                        gradient = new LinearGradient(0, 0, width, height,
                            _colors,_locations,
                            _tileMode);
                        break;
                }

            return gradient;
        }
    }
}

Solution 6:[6]

The XFGloss project adds the ability to add gradients via XAML.

For example:

    <xfg:ContentPageGloss.BackgroundGradient>
        <xfg:Gradient Rotation="150">
            <xfg:GradientStep StepColor="White" StepPercentage="0" />
            <xfg:GradientStep StepColor="White" StepPercentage=".5" />
            <xfg:GradientStep StepColor="#ccd9ff" StepPercentage="1" />
        </xfg:Gradient>
    </xfg:ContentPageGloss.BackgroundGradient>
    ...
</ContentPage>

Solution 7:[7]

Here's a ContentView of mine that I wrote. You can use as-is in your PCL/Core project without a CustomRender. It has a dependancy on SkiaSharp though.

It has an ItemTemplate and Bindable properties.

Xamarin Forms Gradient Content View

Solution 8:[8]

The Android draw mehtod was not working for me so, so I extended it a bit:

    protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
    {
        Android.Graphics.LinearGradient gradient;

        using (var path = new Android.Graphics.Path())
        using(var paint = new Android.Graphics.Paint()
            {
                Dither = true,
                AntiAlias = true,
            })
        using (Android.Graphics.Path.Direction direction = Android.Graphics.Path.Direction.Cw)
        using (var rect = new Android.Graphics.RectF(0, 0, (float)canvas.Width, (float)canvas.Height))
        {
            if (Element.Orientation == StackOrientation.Vertical)
                gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height, this.StartColor.ToAndroid(),
                   this.EndColor.ToAndroid(),
                   Android.Graphics.Shader.TileMode.Mirror);
            else
                gradient = new Android.Graphics.LinearGradient(0, 0, Width, 0, this.StartColor.ToAndroid(),
                   this.EndColor.ToAndroid(),
                   Android.Graphics.Shader.TileMode.Mirror);

            path.AddRect(rect, direction);
            paint.SetShader(gradient);
            canvas.DrawPath(path, paint);
        }
        base.DispatchDraw(canvas);
    }

Solution 9:[9]

the I Edited the class given by @na2axl to use it to give rbga colors with this format "R,G,B,A:R,G,B,A". All colors will be separated by colon and their values will be separated by qoma (,) like "255,255,255,100:255,255,255,0"

public class GradientLayout : StackLayout
{
    public string ColorsList { get; set; }

    public Color[] Colors
    {
        get
        {
            string[] rgbacolor = ColorsList.Split(':');
            Color[] colors = new Color[rgbacolor.Length];
            for (int i = 0; i < rgbacolor.Length; i++) {
                string[] colorcodes = rgbacolor[i].Trim().Split(',');
                double r = double.Parse(colorcodes[0].Trim());
                double g = double.Parse(colorcodes[1].Trim());
                double b = double.Parse(colorcodes[2].Trim());
                double a = double.Parse(colorcodes[3].Trim());
                colors[i] = Color.FromRgba(r,g,b,a);
                //Color.FromHex(rgbacolor[i].Trim());
            }
            return colors;
        }
    }

    public GradientColorStackMode Mode { get; set; }
}

Solution 10:[10]

The best solution is the one described here at https://devblogs.microsoft.com/xamarin/magic-gradients-xamarinforms/

Install the nuget MagicGradients

In app.xaml add the line

<Application.Resources>
<!-- ..... -->
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
<Setter Property="ControlTemplate">
<Setter.Value>
<ControlTemplate>
<Grid> 
<magicGradients:GradientView VerticalOptions="FillAndExpand">
<magicGradients:GradientView.GradientSource>
<magicGradients:LinearGradient Angle="320">
<magicGradients:GradientStop Color="#338af9" Offset="0" />
<magicGradients:GradientStop Color="#2ff8ff" Offset="1" />
</magicGradients:LinearGradient>
</magicGradients:GradientView.GradientSource>
</magicGradients:GradientView>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ..... --->
</Application.Resources>

The above will apply Linear gradient to your ContentPage

Solution 11:[11]

Starting Xamarin Forms 4.8 you can add the built-in gradient.

<Frame BorderColor="LightGray"
   HasShadow="True"
   CornerRadius="12"
   HeightRequest="120"
   WidthRequest="120">
<Frame.Background>
    <RadialGradientBrush Center="0.5,0.5"
                         Radius="0.5">
        <GradientStop Color="Red"
                      Offset="0.1"/>
        <GradientStop Color="DarkBlue"
                      Offset="1.0"/>
    </RadialGradientBrush>
</Frame.Background>

Source and details on Microsoft DevBlogs: https://devblogs.microsoft.com/xamarin/xamarinforms-4-8-gradients-brushes/

Solution 12:[12]

To use dynamic Resources, you will have to make your properties bindable, like this

    public static BindableProperty StartColorProperty = BindableProperty.Create(nameof(CustomContentPage), typeof(Color), typeof(CustomButton), default(Color), defaultBindingMode: BindingMode.OneWay);

    public Color StartColor
    {
        get { return (Color)GetValue(StartColorProperty); }
        set { SetValue(PaddingProperty, value); }
    }


    public static BindableProperty EndColorProperty = BindableProperty.Create(nameof(CustomContentPage), typeof(Color), typeof(CustomButton), default(Color), defaultBindingMode: BindingMode.OneWay);

    public Color EndColor
    {
        get { return (Color)GetValue(EndColorProperty); }
        set { SetValue(PaddingProperty, value); }
    }