Forked from alexlau811/OverrideFormattedStringExtension.cs
Created
February 19, 2016 15:27
-
-
Save Adam--/09f79e1033e21507b6a6 to your computer and use it in GitHub Desktop.
Override default FormattedString behaviour to allow custom font to be used in Label of Xamarin.Forms.Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class OverrideFormattedStringExtension | |
{ | |
// | |
// Static Methods | |
// | |
public static SpannableString ToAttributed(this FormattedString formattedString, Font defaultFont, Color defaultForegroundColor, TextView view) | |
{ | |
if (formattedString == null) | |
{ | |
return null; | |
} | |
StringBuilder stringBuilder = new StringBuilder(); | |
foreach (Span current in formattedString.Spans) | |
{ | |
if (current.Text != null) | |
{ | |
stringBuilder.Append(current.Text); | |
} | |
} | |
SpannableString spannableString = new SpannableString(stringBuilder.ToString()); | |
int num = 0; | |
foreach (Span current2 in formattedString.Spans) | |
{ | |
if (current2.Text != null) | |
{ | |
int num2 = num; | |
int num3 = num2 + current2.Text.Length; | |
num = num3; | |
if (current2.ForegroundColor != Color.Default) | |
{ | |
spannableString.SetSpan(new ForegroundColorSpan(current2.ForegroundColor.ToAndroid()), num2, num3, SpanTypes.InclusiveExclusive); | |
} | |
else | |
{ | |
if (defaultForegroundColor != Color.Default) | |
{ | |
spannableString.SetSpan(new ForegroundColorSpan(defaultForegroundColor.ToAndroid()), num2, num3, SpanTypes.InclusiveExclusive); | |
} | |
} | |
if (current2.BackgroundColor != Color.Default) | |
{ | |
spannableString.SetSpan(new BackgroundColorSpan(current2.BackgroundColor.ToAndroid()), num2, num3, SpanTypes.InclusiveExclusive); | |
} | |
if (! IsSpanDefault(current2)) | |
{ | |
spannableString.SetSpan(new FontSpan(current2.Font, view), num2, num3, SpanTypes.InclusiveInclusive); | |
} | |
else | |
{ | |
if (defaultFont != Font.Default) | |
{ | |
spannableString.SetSpan(new FontSpan(defaultFont, view), num2, num3, SpanTypes.InclusiveInclusive); | |
} | |
} | |
} | |
} | |
return spannableString; | |
} | |
public static bool IsSpanDefault(Span self) | |
{ | |
return self.FontFamily == null && self.FontSize == Device.GetNamedSize(NamedSize.Default, typeof(Label)) && self.FontAttributes == FontAttributes.None; | |
} | |
// | |
// Nested Types | |
// | |
private class FontSpan : MetricAffectingSpan | |
{ | |
public Font Font | |
{ | |
get; | |
private set; | |
} | |
public TextView TextView | |
{ | |
get; | |
private set; | |
} | |
public FontSpan(Font font, TextView view) | |
{ | |
this.Font = font; | |
this.TextView = view; | |
} | |
public override void UpdateDrawState(TextPaint tp) | |
{ | |
this.Apply(tp); | |
} | |
public override void UpdateMeasureState(TextPaint p) | |
{ | |
this.Apply(p); | |
} | |
private void Apply(Paint paint) | |
{ | |
paint.SetTypeface(this.Font.ToTypeface()); | |
float value = this.Font.ToScaledPixel(); | |
paint.TextSize = TypedValue.ApplyDimension(ComplexUnitType.Sp, value, this.TextView.Resources.DisplayMetrics); | |
} | |
} | |
public static Typeface ToTypeface(this Font self) | |
{ | |
if (self == Font.Default) | |
{ | |
return Typeface.Default; | |
} | |
TypefaceStyle style = TypefaceStyle.Normal; | |
if ((self.FontAttributes & (FontAttributes.Bold | FontAttributes.Italic)) == (FontAttributes.Bold | FontAttributes.Italic)) | |
{ | |
style = TypefaceStyle.BoldItalic; | |
} | |
else | |
{ | |
if ((self.FontAttributes & FontAttributes.Bold) != FontAttributes.None) | |
{ | |
style = TypefaceStyle.Bold; | |
} | |
else | |
{ | |
if ((self.FontAttributes & FontAttributes.Italic) != FontAttributes.None) | |
{ | |
style = TypefaceStyle.Italic; | |
} | |
} | |
} | |
if (self.FontFamily != null) | |
{ | |
var typeface = Typeface.Create(self.FontFamily, style); | |
if (typeface.Equals(Typeface.Default)) | |
{ | |
try | |
{ | |
return Typeface.CreateFromAsset(Android.App.Application.Context.Assets, "fonts/" + self.FontFamily); | |
} | |
catch (Exception ex) | |
{ | |
try | |
{ | |
return Typeface.CreateFromFile("fonts/" + self.FontFamily); | |
} | |
catch (Exception ex1) | |
{ | |
return typeface; // which is Typeface.Default | |
} | |
} | |
} | |
return typeface; // which is Typeface.Default | |
} | |
return Typeface.Create(Typeface.Default, style); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[assembly: ExportRenderer(typeof(Label), typeof(OverrideLabelRenderer))] | |
public class OverrideLabelRenderer : LabelRenderer | |
{ | |
protected override void OnElementChanged(ElementChangedEventArgs<Label> e) | |
{ | |
base.OnElementChanged(e); | |
this.UpdateText(); | |
} | |
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) | |
{ | |
base.OnElementPropertyChanged(sender, e); | |
if (e.PropertyName == Label.TextColorProperty.PropertyName) | |
{ | |
this.UpdateText(); | |
return; | |
} | |
if (e.PropertyName == Label.FontProperty.PropertyName) | |
{ | |
this.UpdateText(); | |
return; | |
} | |
if (e.PropertyName == Label.TextProperty.PropertyName || e.PropertyName == Label.FormattedTextProperty.PropertyName) | |
{ | |
this.UpdateText(); | |
} | |
} | |
private void UpdateText() | |
{ | |
if (base.Element.FormattedText != null) | |
{ | |
var view = Control as TextView; | |
FormattedString formattedString = base.Element.FormattedText ?? base.Element.Text; | |
view.TextFormatted = formattedString.ToAttributed(base.Element.Font, base.Element.TextColor, view); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment