Добавление фона градиента в макеты в визуальной студии Xamarin Forms

Я новичок в Xamarin Forms, я создаю ContentPage для Menu. Мне нужен линейный градиентный цвет на его фоне. Но я не могу найти ссылку, которая подскажет мне, как создать цвет фона. Я также хочу, чтобы это цветное место на фоне кнопки, например, селектор в android. Если у вас есть какая-либо информация, ответьте.

Ответ 1

В приведенном ниже коде мы можем установить горизонтальный и вертикальный градиент (я положил его в #region) для любого макета ниже. Я пишу для StackLayout, если вы хотите написать другой макет, просто замените макет на StackLayout.

В 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);
      }
    }
 }

В 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>

Ответ 2

Для тех, кто хочет полнофункциональный градиент в приложениях Xamarin.Forms, есть мой код:

В вашем 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
    }
}

В вашем проекте iOS

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);
        }
    }
}

В вашем проекте Android

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);
            }
        }
    }
}

В проекте UWP

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);
            }
        }
    }
}

На ваших страницах XAML

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

    <!-- Your content -->

</renderers:GradientLayout>

Надеюсь, это поможет!

Ответ 3

Добавьте SkiaSharp Nuget в свой проект togehter с этим классом. Используйте его в своем xaml, если вам нужен градиент.

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);
    }

Ответ 4

На данный момент нет реальной функциональности рисования, чтобы сделать это. Возможно, вы захотите установить изображение в качестве фона, вы можете предоставить много картинок для разных папок (hdpi, mdpi, xhdpi и т.д.). Или вы можете использовать собственные средства визуализации, чтобы расширить класс ContentPage в свой.

Вы можете посмотреть это обсуждение на форумах Xamarin. https://forums.xamarin.com/discussion/22440/gradient-as-background-color

Ответ 5

Первый комментарий когда-либо на SO.

используя ответ na2xl в качестве эффекта

Эффекты могут быть прикреплены к другому компоненту, могут использоваться повторно и не заставляют вас создавать подклассы компонентов Forms.

Я добавил систему локации, чтобы настроить, где каждый цвет начинается и заканчивается в градиенте - 0 абсолютное начало /1 абсолютный конец.

в 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
    }
}

в проекте iOS

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");
        }
    }
}

** в проекте Android **

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;
        }
    }
}

Ответ 6

Проект XFGloss добавляет возможность добавления градиентов через XAML.

Например:   

    <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>

Ответ 7

Вот мой ContentView, который я написал. Вы можете использовать как есть в своем проекте PCL/Core без CustomRender. Это зависит от SkiaSharp, хотя.

У него есть свойства ItemTemplate и Bindable.

Вид содержимого градиента форм Xamarin

Ответ 8

Механизм рисования Android у меня не работал, поэтому я немного его расширил:

    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);
    }

Ответ 9

Чтобы использовать динамические ресурсы, вам нужно будет сделать ваши свойства связуемыми, например

    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); }
    }