user4545768
user4545768

Reputation:

Change typeface of formatted text in Xamarin

I have a label with formatted text and I wanna change its font style(I mean typeface). I tried using Custom Label Rendering( like doing it for the normal text) ,but it is not getting reflected. My doubt is whether we can change typeface of formatted text (since it is working fine for text (not formatted text) of label).

This is my .xaml file code

<Label x:Name = "invosTitle" Grid.Column = "0" Grid.Row = "0" Grid.ColumnSpan = "3"  HorizontalOptions = "CenterAndExpand">
        <Label.FormattedText>
            <FormattedString>
                <FormattedString.Spans>
                    <Span Text = "abcd"  ForegroundColor = "White" ></Span>
                    <Span Text = "   "></Span>
                    <Span Text = "efgh" ForegroundColor = "Gray"></Span>
                </FormattedString.Spans>
            </FormattedString>
        </Label.FormattedText>
</Label>

and CustomLabelRenderer code is

protected override void OnElementPropertyChanged (object sender , PropertyChangedEventArgs e) 
{
    base.OnElementPropertyChanged(sender, e);
    var label = (TextView)Control; 
    Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets,  "Fonts/microsoftjhengheibold.otf");
    label.Typeface = font;
    label.SetTypeface (font, TypefaceStyle.Bold);
}

Upvotes: 4

Views: 2858

Answers (2)

VeYroN
VeYroN

Reputation: 760

Just in case anyone needs to keep the same font and just change the spans color here's the code:

[assembly: ExportRenderer (typeof (Label), typeof (LabelCustomRenderer))]
namespace YourNamespace
{

public class LabelCustomRenderer : LabelRenderer
{
    protected override void OnElementChanged (ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged (e);
        Init ();
    }

    protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged (sender, e);
        if (e.PropertyName == Label.FontFamilyProperty.PropertyName) {
            Init ();
        }
    }

    void Init(){
        if (Control != null) {
            var label = (CustomLabel)Element;
            if (label.FontName != null) {
                if (label.FormattedText != null) {
                    SpannableStringBuilder ssb = new SpannableStringBuilder ();

                    foreach (Span span in label.FormattedText.Spans) {
                        ssb.Append (span.Text);
                        ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan (span.ForegroundColor.ToAndroid ());
                        ssb.SetSpan (foregroundColorSpan, ssb.Length () - span.Text.Length, ssb.Length (), SpanTypes.ExclusiveExclusive);
                    }
                    Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "Fonts/" + label.FontFamily);
                    Control.Typeface = font;
                    Control.TextSize = (float)label.FontSize;
                    Control.SetText (ssb, TextView.BufferType.Normal);
                } else {
                    Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "Fonts/" + label.FontFamily);
                    Control.Typeface = font;
                    Control.TextSize = (float)label.FontSize;
                }
            }
        }
    }
}
}

Upvotes: 0

Daniel May
Daniel May

Reputation: 8246

When using the FormattedString element, you can change the typeface of each Span individually with the FontFamily attribute. You don't need a custom label renderer to achieve this.

<Span Text="abcd"  
      ForegroundColor="White" 
      FontFamily="Helvetica" />

This is documented in the Xamarin "Working with fonts" documentation.

Upvotes: 2

Related Questions