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.
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>
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, 0); gradientLayer.EndPoint = new CGPoint(0.5, 1); break; case GradientColorStackMode.ToBottom: gradientLayer.StartPoint = new CGPoint(0.5, 1); gradientLayer.EndPoint = new CGPoint(0.5, 0); break; case GradientColorStackMode.ToTopLeft: gradientLayer.StartPoint = new CGPoint(1, 0); gradientLayer.EndPoint = new CGPoint(0, 1); 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, 1); gradientLayer.EndPoint = new CGPoint(0, 0); 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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With