使用自定义文本描边渲染器后无法设置 TextColor Xamarain.Forms

Can't set TextColor after using Custom Text Stroke Renderer Xamarain.Forms

我的项目中有这个自定义文本描边渲染器,但在使用它之后,我无法再在 XAML 和 ViewModel 中手动设置或绑定我的 TextColor 与十六进制颜色或系统颜色选项。我的文本始终具有默认的 TextColor,即灰色。

#CustomTextStroke.cs

namespace Project11.CustomForms
{
  public class CustomTextStroke : Label
  {
  }
}

#StrokeTextView.cs

namespace Project11.CustomForms
{
  public class StrokeTextView : TextView
  {
    private TextView borderText = null;

    public StrokeTextView(Context context) : base(context)
    {
        borderText = new TextView(context);

        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 = 5;         // sets the stroke width                        
        tp1.SetStyle(Style.Stroke);
        borderText.SetTextColor(Color.White);  // 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);
    }
  }
}

#CustomTextStrokeRenderer

[assembly: ExportRenderer(typeof(CustomTextStroke), typeof(CustomTextStrokeRenderer))]
namespace Project11.Droid.CustomRenderer
{
  public class CustomTextStrokeRenderer : LabelRenderer
  {
    Context context;

    public CustomTextBorderRenderer(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);
            strokeTextView.Text = e.NewElement.Text;
            SetNativeControl(strokeTextView);
        }
    }
  }
}

#XAML

<customforms:CustomTextStroke Scale="1.2" Text="Please Enter Here!" FontSize="22" 
 TextColor="Cyan" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" 
                                      />
<customforms:CustomTextStroke Scale="1.2" Text="Confirm" FontSize="22" 
 TextColor="{Binding ColorChange}" VerticalOptions="CenterAndExpand" 
 HorizontalOptions="CenterAndExpand" 
                                      />

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

在 Github github.com/borisoprit/Textstrokecolor

上做了一个例子

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

在命名空间上方添加这个 [程序集:ExportRenderer(typeof(MyCustomLabel), typeof(MyLabelRenderer))]

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;
            Control.TextColor = UIColor.Yellow;
        }
    }
}

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

在上面添加这个命名空间 [程序集:ExportRenderer(typeof(MyCustomLabel), typeof(MyLabelRenderer))]

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

在主

中添加这个class
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); }
    }
}

还有这个Android

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

然后在 xaml

中这样使用
<StackLayout>
    <Frame
        Padding="24"
        BackgroundColor="#2196F3"
        CornerRadius="0">
        <Label
            FontSize="36"
            HorizontalTextAlignment="Center"
            Text="Welcome to Xamarin.Forms!"
            TextColor="White"
            />
    </Frame>
    <labelupdatedemo:MyCustomLabel 
        x:Name = "BTTextStatus"
        FontAttributes="Bold"
        Text="Label"
        FontSize="Large"
         StrokeColor="Yellow"
        StrokeThickness="5"
        TextColor="Green"/>      
    
</StackLayout>