如何在Xamarin Forms中页面标题下方的边框线中添加渐变?
我要实现的示例是here。
[使用自定义渲染器创建Xamarin.Forms视图,该渲染器在iOS和Android的视图中绘制渐变。然后将该视图放置在所需的任何位置,大概位于标题或标题栏的下方。
首先阅读有关制作自定义渲染器的文档:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/
我从Xamarin.Forms框视图开始尝试了此操作。
首先在Xamarin.Forms核心共享项目中创建一个新类,该类继承自BoxView,并为起始,中间和结束颜色设置3个可绑定属性:
using System;
using Xamarin.Forms;
namespace YourNameSpace
{
public class GradientView : BoxView
{
public static readonly BindableProperty StartColorProperty =
BindableProperty.Create(
nameof(StartColor),
typeof(Color),
typeof(GradientView),
Color.Transparent);
public Color StartColor
{
get
{
return (Color)GetValue(StartColorProperty);
}
set
{
SetValue(StartColorProperty, value);
}
}
public static readonly BindableProperty MiddleColorProperty =
BindableProperty.Create(
nameof(MiddleColor),
typeof(Color),
typeof(GradientView),
Color.Transparent);
public Color MiddleColor
{
get
{
return (Color)GetValue(MiddleColorProperty);
}
set
{
SetValue(MiddleColorProperty, value);
}
}
public static readonly BindableProperty EndColorProperty =
BindableProperty.Create(
nameof(EndColor),
typeof(Color),
typeof(GradientView),
Color.Transparent);
public Color EndColor
{
get
{
return (Color)GetValue(EndColorProperty);
}
set
{
SetValue(EndColorProperty, value);
}
}
}
}
在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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestUITest"
mc:Ignorable="d"
x:Class="TestUITest.MainPage"
Title="Gradient View"
BackgroundColor="Black">
<StackLayout>
<!-- Place new controls here -->
<local:GradientView
StartColor="DarkBlue"
MiddleColor="LightBlue"
EndColor="DarkBlue"
HeightRequest="5" />
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="White"/>
</StackLayout>
</ContentPage>
还将您的导航栏设置为黑色(以匹配您的屏幕截图),因此在您的Xamarin.Forms应用程序类中:
public App()
{
InitializeComponent();
var navPage = new NavigationPage(new MainPage());
navPage.BarBackgroundColor = Color.Black;
navPage.BarTextColor = Color.LightBlue;
MainPage = navPage;
}
现在用于特定于平台的渲染器:
Android:
using System;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using YourNameSpace;
using YourNameSpace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(GradientView),typeof(GradientViewRenderer))]
namespace YourNameSpace.Droid
{
public class GradientViewRenderer : BoxRenderer
{
public GradientViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
GradientView formsGradientView = Element as GradientView;
int[] colors = {
Convert.ToInt32(formsGradientView.StartColor.ToHex().Replace("#", "0x"), 16),
Convert.ToInt32(formsGradientView.MiddleColor.ToHex().Replace("#", "0x"), 16),
Convert.ToInt32(formsGradientView.EndColor.ToHex().Replace("#", "0x"), 16)
};
var gradeDrawable = new GradientDrawable(GradientDrawable.Orientation.LeftRight, colors);
ViewGroup.SetBackgroundDrawable(gradeDrawable);
}
}
}
}
iOS:
using System;
using CoreAnimation;
using CoreGraphics;
using YourNameSpace;
using YourNameSpace.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(GradientView), typeof(GradientViewRenderer))]
namespace YourNameSpace.iOS
{
public class GradientViewRenderer : BoxRenderer
{
public override void Draw(CGRect rect)
{
//base.Draw(rect);
GradientView formsGradientView = Element as GradientView;
var currentContext = UIGraphics.GetCurrentContext();
currentContext.SaveState();
var colorSpace = CGColorSpace.CreateDeviceRGB();
var startColor = formsGradientView.StartColor;
var startColorComponents = startColor.ToCGColor().Components;
var middleColor = formsGradientView.MiddleColor;
var middleColorComponents = middleColor.ToCGColor().Components;
var endColor = formsGradientView.EndColor;
var endColorComponents = endColor.ToCGColor().Components;
nfloat[] colorComponents = {
startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3],
middleColorComponents[0], middleColorComponents[1], middleColorComponents[2], middleColorComponents[3],
endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3]
};
nfloat[] locations = { 0f, 0.5f, 1f };
var gradient = new CGGradient(colorSpace, colorComponents, locations);
var startPoint = new CGPoint(0, NativeView.Bounds.Height);
var endPoint = new CGPoint(NativeView.Bounds.Width, NativeView.Bounds.Height);
currentContext.DrawLinearGradient(gradient, startPoint, endPoint, CGGradientDrawingOptions.None);
currentContext.RestoreState();
}
}
}
如何在Xamarin Forms中页面标题下方的边框线中添加渐变?
我创建自定义渲染以创建渐变边框。
首先,您需要定义渲染:
public class GradientViewRender : View
{
public static readonly BindableProperty GradientColorsProperty = BindableProperty.Create<GradientViewRender, Color[]>(p => p.GradientColors, new Color[]{Color.White} );
public Color[] GradientColors
{
get { return (Color[])base.GetValue(GradientColorsProperty); }
set { base.SetValue(GradientColorsProperty, value); }
}
public static readonly BindableProperty ViewHeightProperty = BindableProperty.Create<GradientViewRender, double>(p => p.ViewHeight, 0);
public double ViewHeight
{
get { return (double)base.GetValue(ViewHeightProperty); }
set { base.SetValue(ViewHeightProperty, value); }
}
public static readonly BindableProperty LeftToRightProperty = BindableProperty.Create<GradientViewRender, bool>(p => p.LeftToRight, true);
public bool LeftToRight
{
get { return (bool)base.GetValue(LeftToRightProperty); }
set { base.SetValue(LeftToRightProperty, value); }
}
}
此渲染采用颜色数组,这样您可以提供渐变所需的尽可能多的颜色。
然后您可以在android中实现此渲染。
public class GradientViewRenderer : Xamarin.Forms.Platform.Android.ViewRenderer<GradientTest.GradientViewRender, View>
{
LinearLayout layout;
Xamarin.Forms.Color[] gradientColors;
double viewHeight;
protected override void OnElementChanged(ElementChangedEventArgs<GradientTest.GradientViewRender> e)
{
base.OnElementChanged(e);
if (Control == null)
{
layout = new LinearLayout(Application.Context);
layout.SetBackgroundColor(Color.White);
gradientColors = (Xamarin.Forms.Color[])e.NewElement.GradientColors;
viewHeight = (double)e.NewElement.ViewHeight;
CreateLayout();
}
if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
}
if (e.NewElement != null)
{
// Configure the control and subscribe to event handlers
gradientColors = (Xamarin.Forms.Color[])e.NewElement.GradientColors;
viewHeight = (double)e.NewElement.ViewHeight;
CreateLayout();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == GradientViewRender.ViewHeightProperty.PropertyName)
{
this.viewHeight = (double)this.Element.ViewHeight;
CreateLayout();
}
else if (e.PropertyName == GradientViewRender.GradientColorsProperty.PropertyName)
{
this.gradientColors = (Xamarin.Forms.Color[])this.Element.GradientColors;
CreateLayout();
}
}
private void CreateLayout()
{
layout.SetMinimumWidth((int)viewWidth);
layout.SetMinimumHeight((int)viewHeight);
CreateGradient();
SetNativeControl(layout);
}
public void CreateGradient()
{
//Need to convert the colors to Android Color objects
int[] androidColors = new int[gradientColors.Count()];
for (int i = 0; i < gradientColors.Count(); i++)
{
Xamarin.Forms.Color temp = gradientColors[i];
androidColors[i] = temp.ToAndroid();
}
GradientDrawable gradient = new GradientDrawable(GradientDrawable.Orientation.LeftRight, androidColors);
if (roundCorners)
gradient.SetCornerRadii(new float[] { cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius });
layout.SetBackground(gradient);
}
}
关于更多详细信息,您可以看一下:
https://baglabs.com/2017/07/14/creating-gradients-xamarin-forms/
您可以从以下位置获得样品:
https://github.com/baileysh9/xamarin_forms_gradient
最后,您可以像这样获得此渐变边框:
您可以通过GradientColors更改不同的颜色。
如果我的回复对您有帮助,请记住将我的回复标记为答案,谢谢。