Tuesday 20 March 2018

Horizontal and Vertical Gradient Color in Xamarin.Forms

Introduction

Sometimes, we may get the requirement to set Gradient Color for Layout or page. In this article, we can learn how we can set a Gradient Color for Layout or Page using CustomRenderer.
Requirements
  • This article source code is prepared by using Visual Studio. And it is better to install the latest Visual Studio updates from here.
  • This article is prepared on a MAC machine.
  • This sample project is Xamarin.Forms PCL project.
  • This sample app is targeted for Android, iOS. And tested for Android & iOS.
Description
The creation of a Xamarin.Forms project is very simple in Visual Studio for Mac. It will create three projects:
  1. Shared Code
  2. Xamarin.Android
  3. Xamarin.iOS
The Mac system with Visual Studio for Mac  doesn't support Windows projects (UWP, Windows, Windows Phone)
The following steps will show you how to create Xamarin.Forms projects in a Mac system with Visual Studio.
First, open Visual Studio for Mac. And click on New Project.

After that, we need to select whether you're doing Xamarin.Forms or Xamarin.Android or Xamarin.iOS project. If we want to create Xamarin.Forms project just follow the below screenshot.

Then, we have to give the app name; i.e., GradientColorDemo.

Note
In the above screen under Shared Code, select Portable class Library or Use Shared Library.
Then, click on Next Button and the following screenshot will be displayed. In that screen, we have to browse the file path where we want to save that application on our PC.

After clicking on the create button it will create the RoundedCornerViewDemo Xamarin.Forms project like below.

And the project structure will be:
  • GradientColorDemo: It is for Shared Code
  • GradientColorDemo.Droid: It is for Android.
  • GradientColorDemo.iOS: It is for iOS

We need to follow the below steps to set Gradient Color for StackLayout.
Portable Class Library (PCL)
Step 1:
In PCL, create a class name GradientColorStack inside the CustomControls folder and which should inherit from StackLayout like below.
GradientColorStack.cs
  1. using Xamarin.Forms;      
  2.       
  3. namespace GradientColorDemo.CustomControls      
  4. {      
  5.     public class GradientColorStack : StackLayout        
  6.     {        
  7.         public Color StartColor { getset; }        
  8.         public Color EndColor { getset; }        
  9.     }        
  10. }      

Step 2:


Create your own Xaml page named GradientColorPage.xaml, and make sure to refer to  "GradientColorStack" class in Xaml by declaring a namespace for its location and using the namespace prefix on the control element. The following code example shows how the "GradientColorStack" renderer class can be consumed by a XAML page:


GradientColorPage.xaml

  1. <?xml version="1.0" encoding="utf-8"?>      
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
  3. xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
  4. xmlns:local="clr-namespace:GradientColorDemo.CustomControls; assembly:GradientColorDemo" 
  5. x:Class="GradientColorDemo.Views.GradientColorPage">      
  6. <Grid VerticalOptions="FillAndExpand" RowSpacing="0">      
  7.         <Grid.RowDefinitions>      
  8.             <RowDefinition Height="*"/>    
  9.             <RowDefinition Height="*"/>    
  10.         </Grid.RowDefinitions>      
  11.         <Grid Grid.Row="0" BackgroundColor="#3e5151">       
  12.             <StackLayout VerticalOptions="Center">      
  13.                 <Label Text="Normal color for StackLayout" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"  TextColor="White"/>      
  14.             </StackLayout>      
  15.         </Grid>      
  16.         <Grid Grid.Row="1">      
  17.             <local:GradientColorStack StartColor="#3e5151" EndColor="#decba4">      
  18.                 <StackLayout VerticalOptions="CenterAndExpand">      
  19.                     <Label Text="Horizontal Gradient color for StackLayout" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"   TextColor="White"/>      
  20.                 </StackLayout>      
  21.             </local:GradientColorStack>     
  22.         </Grid>      
  23.     </Grid>      
  24. </ContentPage>     

Note:

The "local" namespace prefix can be named anything. However, the clr-namespace and assembly values must match the details of the custom renderer class. Once the namespace is declared the prefix is used to reference the custom control.

GradientColorPage.xaml.cs


  1. using Xamarin.Forms;    
  2.     
  3. namespace GradientColorDemo.Views    
  4. {    
  5.     public partial class GradientColorPage : ContentPage    
  6.     {    
  7.         public GradientColorPage()    
  8.         {    
  9.             InitializeComponent();    
  10.         }    
  11.     }    
  12. }    

Xamarin.Android:


In Android project, create a class with GradientColorStackRenderer name inside the CustomControls folder: 


GradientColorStackRenderer.cs

  1. using System;    
  2. using GradientColorDemo.Droid;    
  3. using GradientColorDemo.CustomControls;    
  4. using Xamarin.Forms;    
  5. using Xamarin.Forms.Platform.Android;    
  6.     
  7. [assembly: ExportRenderer(typeof(GradientColorStack), typeof(GradientColorStackRenderer))]    
  8.     
  9. namespace GradientColorDemo.Droid    
  10. {    
  11.     public class GradientColorStackRenderer : VisualElementRenderer<StackLayout>    
  12.     {    
  13.         private Color StartColor { getset; }    
  14.         private Color EndColor { getset; }    
  15.     
  16.         protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)    
  17.         {    
  18.             #region for Vertical Gradient      
  19.             //var gradient = new Android.Graphics.LinearGradient(0, 0, 0, Height,  
  20.             #endregion    
  21.             #region for Horizontal Gradient      
  22.                var gradient = new Android.Graphics.LinearGradient(0, 0, Width, 0,   
  23.             #endregion       
  24.                 this.StartColor.ToAndroid(),    
  25.                 this.EndColor.ToAndroid(),    
  26.                 Android.Graphics.Shader.TileMode.Mirror);    
  27.     
  28.             var paint = new Android.Graphics.Paint()    
  29.             {    
  30.                 Dither = true,    
  31.             };    
  32.             paint.SetShader(gradient);    
  33.             canvas.DrawPaint(paint);    
  34.             base.DispatchDraw(canvas);    
  35.         }    
  36.     
  37.         protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)    
  38.         {    
  39.             base.OnElementChanged(e);    
  40.     
  41.             if (e.OldElement != null || Element == null)    
  42.             {    
  43.                 return;    
  44.             }    
  45.             try    
  46.             {    
  47.                 var stack = e.NewElement as GradientColorStack;    
  48.                 this.StartColor = stack.StartColor;    
  49.                 this.EndColor = stack.EndColor;    
  50.             }    
  51.             catch (Exception ex)    
  52.             {    
  53.                 System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);    
  54.             }    
  55.         }    
  56.     }    
  57.  


Here OnElementChanged method instantiates an Android UI Layout and in that, I mentioned vertical and horizontal gradients within #region.


Output:




Xamarin.iOS:
In iOS project, create a class with GradientColorStackRenderer name inside the CustomControls folder:

GradientColorStackRenderer.cs

  1. using CoreAnimation;    
  2. using CoreGraphics;    
  3. using GradientColorDemo.CustomControls;    
  4. using GradientColorDemo.iOS;    
  5. using Xamarin.Forms;    
  6. using Xamarin.Forms.Platform.iOS;    
  7.     
  8. [assembly: ExportRenderer(typeof(GradientColorStack), typeof(GradientColorStackRenderer))]    
  9.     
  10. namespace GradientColorDemo.iOS    
  11. {    
  12.     public class GradientColorStackRenderer : VisualElementRenderer<StackLayout>    
  13.     {    
  14.         public override void Draw(CGRect rect)    
  15.         {    
  16.             base.Draw(rect);    
  17.             GradientColorStack stack = (GradientColorStack)this.Element;    
  18.             CGColor startColor = stack.StartColor.ToCGColor();    
  19.     
  20.             CGColor endColor = stack.EndColor.ToCGColor();    
  21.   
  22.             #region for Vertical Gradient    
  23.             //var gradientLayer = new CAGradientLayer();   
  24.             #endregion    
  25.   
  26.             #region for Horizontal Gradient      
  27.             var gradientLayer = new CAGradientLayer()    
  28.             {    
  29.                 StartPoint = new CGPoint(0, 0.5),    
  30.                 EndPoint = new CGPoint(1, 0.5)    
  31.             };    
  32.             #endregion    
  33.     
  34.             gradientLayer.Frame = rect;    
  35.             gradientLayer.Colors = new CGColor[] { startColor, endColor };    
  36.     
  37.             NativeView.Layer.InsertSublayer(gradientLayer, 0);    
  38.         }    
  39.     }    
  40.   

Here OnElementChanged method instantiates an iOS UI and in that, I mentioned vertical and horizontal gradients within #region.


Output:
   

Please download the sample from below.


No comments:

Post a Comment