如何add/create标注描边?

How to add/create label stroke?

我正在尝试将描边标签添加到我的 Xamarin Forms 应用程序中,起初我认为这很简单,但经过数小时的谷歌搜索后我根本找不到任何东西。

我想要的只是具有 outline/stroke 颜色和厚度属性的相同简单标签控件,如下所示:

<Label Text="Label" TextColor="#0B1751" StrokeColor="#0FBEFE" StrokeThickness="3"/>

提前致谢。

你想达到如下截图的效果吗?

如果是这样,您可以创建一个自定义渲染器来实现它。

在Android中,可以创建两个Textview,使较小的textview位于较大的textview之上。这是代码。 在IOS中可以用同样的方法实现。

[assembly: ExportRenderer(typeof(Label), typeof(MyLabelRenderer))]
namespace LabelUpdateDemo.Droid
{
   public class MyLabelRenderer: LabelRenderer
    {
        Context context;
        public MyLabelRenderer(Context context) : base(context) {
            this.context = context;
        }




        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {

                StrokeTextView strokeTextView = new StrokeTextView(context,Control.TextSize);
                strokeTextView.Text = e.NewElement.Text;
                strokeTextView.SetTextColor(Android.Graphics.Color.Purple);
              //  Control.TextSize=50;
                SetNativeControl(strokeTextView);
            }
        }
    }
}

这是关于 StrokeTextView.

的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Text;
using Android.Util;
using Android.Views;
using Android.Widget;
using static Android.Graphics.Paint;

namespace LabelUpdateDemo.Droid
{
    class StrokeTextView : TextView
    {
        private TextView borderText = null;
        float OriTextSize;
        public StrokeTextView(Context context,float OriTextSize) : base(context)
        {
            borderText = new TextView(context);
            borderText.TextSize = OriTextSize;
            this.TextSize = OriTextSize;
          
            init();
        }
        public StrokeTextView(Context context, IAttributeSet attrs) : base(context, attrs)
        {
            borderText = new TextView(context, attrs);
            init();
        }
        public StrokeTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
        {
            borderText = new TextView(context, attrs, defStyle);
            init();
        }



        public void init()
        {
            TextPaint tp1 = borderText.Paint;
            tp1.StrokeWidth = 15;         // sets the stroke width                        
            tp1.SetStyle(Style.Stroke);
            borderText.SetTextColor(Color.Blue);  // set the stroke color
            borderText.Gravity = Gravity;

        }

     
        public override ViewGroup.LayoutParams LayoutParameters { get => base.LayoutParameters; set => base.LayoutParameters = value; }

        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            string tt = borderText.Text;


            if (tt == null || !tt.Equals(this.Text))
            {
                borderText.Text = Text;
                this.PostInvalidate();
            }

            base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
            borderText.Measure(widthMeasureSpec, heightMeasureSpec);
        }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            base.OnLayout(changed, left, top, right, bottom);
            borderText.Layout(left, top, right, bottom);
        }

        protected override void OnDraw(Canvas canvas)
        {
            borderText.Draw(canvas);
            base.OnDraw(canvas);
        }
    }
}

这是 xamarin 表单中的代码。

    <Label 
            x:Name = "BTTextStatus"
            FontAttributes="Bold"
            Text="Label"
            FontSize="Large"/>

如果你想添加一些自定义渲染器,你可以创建一个自定义标签,然后为这个自定义标签添加behavior

===============更新==================

如果要添加属性,例如StrokeColor="#0FBEFE"StrokeThickness="3"

您可以像下面的代码一样创建一个 customLabel 控件。

  public class MyCustomLabel:Label
    {

    
        public static readonly BindableProperty StrokeColorProperty = BindableProperty.CreateAttached("StrokeColor", typeof(string), typeof(MyCustomLabel), "");
        public string StrokeColor
        {
            get { return base.GetValue(StrokeColorProperty).ToString(); }
            set { base.SetValue(StrokeColorProperty, value); }
        }

        public static readonly BindableProperty StrokeThicknessProperty = BindableProperty.CreateAttached("StrokeThickness", typeof(int), typeof(MyCustomLabel), 0);
        public int StrokeThickness
        {
            get { return (int) base.GetValue(StrokeThicknessProperty); }
            set { base.SetValue(StrokeThicknessProperty, value); }
        }
    }

然后在xaml文件夹中使用。

 <labelupdatedemo:MyCustomLabel 
            x:Name = "BTTextStatus"
            StrokeColor="#0FBEFE"
            StrokeThickness="5"
            HorizontalOptions="CenterAndExpand"
            VerticalOptions="CenterAndExpand"
            TextColor="#0B1751"
            FontSize="Medium"/>

在 Android 自定义渲染器中,如以下代码。

[assembly: ExportRenderer(typeof(MyCustomLabel), typeof(MyLabelRenderer))]
namespace LabelUpdateDemo.Droid
{
   public class MyLabelRenderer: LabelRenderer
    {
        Context context;
        public MyLabelRenderer(Context context) : base(context) {
            this.context = context;
        }




        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            MyCustomLabel  customLabel=(MyCustomLabel) Element;
            var StrokeTextViewColor= customLabel.StrokeColor;

            int StrokeThickness = customLabel.StrokeThickness;
            if (Control != null)
            {

                StrokeTextView strokeTextView = new StrokeTextView(context, Control.TextSize, StrokeTextViewColor,  StrokeThickness);
                strokeTextView.Text = e.NewElement.Text;
                strokeTextView.SetTextColor(Control.TextColors);
            
                SetNativeControl(strokeTextView);
            }
        }


    }
}

这是关于 StrokeTextView.cs

的代码
    class StrokeTextView : TextView
    {
        private TextView borderText = null;
        float OriTextSize;
        public StrokeTextView(Context context,float OriTextSize,string StrokeTextViewColor, int StrokeThickness) : base(context)
        {
            borderText = new TextView(context);
          
            borderText.TextSize = OriTextSize;
            this.TextSize = OriTextSize;
          
            init(StrokeTextViewColor,  StrokeThickness);
        }
        public void init(string StrokeTextViewColor, int StrokeThickness)
        {
            TextPaint tp1 = borderText.Paint;
            tp1.StrokeWidth = StrokeThickness;         // sets the stroke width                        
            tp1.SetStyle(Style.Stroke);
            borderText.SetTextColor(Color.ParseColor(StrokeTextViewColor));  // set the stroke color
            borderText.Gravity = Gravity;

        }

     
        public override ViewGroup.LayoutParams LayoutParameters { get => base.LayoutParameters; set => base.LayoutParameters = value; }

        protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            string tt = borderText.Text;


            if (tt == null || !tt.Equals(this.Text))
            {
                borderText.Text = Text;
                this.PostInvalidate();
            }

            base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
            borderText.Measure(widthMeasureSpec, heightMeasureSpec);
        }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            base.OnLayout(changed, left, top, right, bottom);
            borderText.Layout(left, top, right, bottom);
        }

        protected override void OnDraw(Canvas canvas)
        {
            borderText.Draw(canvas);
            base.OnDraw(canvas);
        }
    }
}

在IOS中,您可以使用以下自定义渲染器来实现。

[assembly: ExportRenderer(typeof(MyCustomLabel), typeof(MyLabelRenderer))]
namespace LabelUpdateDemo.iOS
{
    class MyLabelRenderer: LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            MyCustomLabel myCustomLabel= Element as MyCustomLabel;


            if (Control != null)
            {
                UIStringAttributes strokeTextAttributes = new UIStringAttributes();
                // Here is set the StrokeColor
              
                strokeTextAttributes.StrokeColor = Color.FromHex(myCustomLabel.StrokeColor).ToUIColor(); ; 
                //Here is set the StrokeThickness, IOS is diferert from the android, it border is set to the inside the font.
                strokeTextAttributes.StrokeWidth = -1*myCustomLabel.StrokeThickness;

                Control.AttributedText = new NSAttributedString(Control.Text, strokeTextAttributes);
                Control.TextColor = UIColor.Black;
            }
        }
    }
   

}