使用自定义文本描边渲染器后无法设置 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>
我的项目中有这个自定义文本描边渲染器,但在使用它之后,我无法再在 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);
}
}
}
在主
中添加这个classpublic 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>