Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Add a Gradient in Xamarin forms Toolbar and UINavigationBar

I'm creating a xamarin forms cross platform application for Android and iOS operating systems. I have to add a gradient to the AppBars in both Operating systems( called ToolBar in android and UINavigationBar in ios) is there any way to accomplish this. please help me cope.. with anything.

enter image description here

like image 265
Dehan Wjiesekara Avatar asked Oct 18 '17 12:10

Dehan Wjiesekara


People also ask

How do you use gradient in xamarin forms?

To create a vertical linear gradient, create a LinearGradientBrush object and set its StartPoint to (0,0) and its EndPoint to (0,1). Then, add two or more GradientStop objects to the LinearGradientBrush. GradientStops collection, that specify the colors in the gradient and their positions.


1 Answers

You should use a custom render, like this:

In your PCL or Shared Project:

public class NavigationPageGradientHeader : NavigationPage
{
    public NavigationPageGradientHeader(Page root) : base(root)
    {
    }
    
    public static readonly BindableProperty RightColorProperty =
      BindableProperty.Create(propertyName: nameof(RightColor),
          returnType: typeof(Color),
          declaringType: typeof(NavigationPageGradientHeader),
          defaultValue: Color.Accent);

    public static readonly BindableProperty LeftColorProperty =
       BindableProperty.Create(propertyName: nameof(LeftColor),
           returnType: typeof(Color),
           declaringType: typeof(NavigationPageGradientHeader),
           defaultValue: Color.Accent);

    public Color RightColor
    {
        get { return (Color)GetValue(RightColorProperty); }
        set { SetValue(RightColorProperty, value); }
    }

    public Color LeftColor
    {
        get { return (Color)GetValue(LeftColorProperty); }
        set { SetValue(LeftColorProperty, value); }
    }
}

[UPDATE]

I've taken the time to create an example, you can see it in Github.

Then in your Android project:

[assembly: ExportRenderer(typeof(NavigationPageGradientHeader), typeof(NavigationPageGradientHeaderRenderer))]
namespace YournameSpace.Droid
{
    public class NavigationPageGradientHeaderRenderer : NavigationRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
        {
            base.OnElementChanged(e);

            //run once when element is created
            if (e.OldElement != null || Element == null)
            {
            return;
            }

            var control = (NavigationPageGradientHeader)this.Element;
            var context = (MainActivity)this.Context;

            context.ActionBar.SetBackgroundDrawable(new GradientDrawable(GradientDrawable.Orientation.RightLeft, new int[] { control.RightColor.ToAndroid(), control.LeftColor.ToAndroid() }));
        }
    }
}

If you use FormsAppCompatActivity in your MainActivity Just add a drawable in gradient like this:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >

  <gradient
      android:angle="180"
      android:centerColor="#26C986"
      android:endColor="#109F8D"
      android:startColor="#36ED81"
      android:type="linear" />

</shape>

Then in your Toolbar.axml file call this drawable:

<android.support.v7.widget.Toolbar
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/toolbar"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@drawable/gradient"
   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
   android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

And in you iOs project:

[assembly: ExportRenderer(typeof(NavigationPageGradientHeader), typeof(NavigationPageGradientHeaderRenderer))]
namespace YourNameSpace.iOS
{
    public class NavigationPageGradientHeaderRenderer: NavigationRenderer
    {
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            var control = (NavigationPageGradientHeader)this.Element;

            var gradientLayer = new CAGradientLayer();
            gradientLayer.Bounds = NavigationBar.Bounds;
            gradientLayer.Colors = new CGColor[] { control.RightColor.ToCGColor(), control.LeftColor.ToCGColor() };
            gradientLayer.StartPoint = new CGPoint(0.0, 0.5);
            gradientLayer.EndPoint = new CGPoint(1.0, 0.5);

            UIGraphics.BeginImageContext(gradientLayer.Bounds.Size);
            gradientLayer.RenderInContext(UIGraphics.GetCurrentContext());
            UIImage image = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            NavigationBar.SetBackgroundImage(image, UIBarMetrics.Default);
        }
    }
}

Finally in your App.xaml.cs file call this control like this:

MainPage = new NavigationPageGradientHeader(new MainPage()) {
     LeftColor = Color.FromHex("#109F8D"),
     RightColor = Color.FromHex("#36ED81")
};

enter image description here

like image 168
Wilson Vargas Avatar answered Sep 22 '22 16:09

Wilson Vargas