如何在Xamarin Forms中页面标题下方的边界线上添加渐变?

问题描述 投票:-1回答:2

如何在Xamarin Forms中页面标题下方的边框线中添加渐变?

我要实现的示例是here

c# xaml xamarin xamarin.forms xamarin.android
2个回答
0
投票

[使用自定义渲染器创建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);
            }
        }
    }
}

enter image description here

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

        }
    }
}

enter image description here


0
投票

如何在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

最后,您可以像这样获得此渐变边框:

enter image description here

您可以通过GradientColors更改不同的颜色。

如果我的回复对您有帮助,请记住将我的回复标记为答案,谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.