3

I need to specify different FontFamily for different Labels in my app. I need to use the default fonts (e.g. Roboto for Android and Helvetica for iOS) with their modifications (e.g. Light, Medium, Bold). As far as I understand I should be using Roboto-Light and Helvetica-Light to get the Light version of the fonts (same for Medium and Bold). In addition to this requirement I need to set the fonts in XAML (like described in documentation) so I end up with this code

<StackLayout BackgroundColor="#F8F8F8" Padding="0, 20, 0, 0">
<Label Text="Black" TextColor="#000000" >
  <Label.FontSize>
    <OnPlatform x:TypeArguments="x:Double"
                iOS="17"
                Android="16"
                WinPhone="16" />
  </Label.FontSize>
  <Label.FontFamily>
    <OnPlatform x:TypeArguments="x:String">
      <OnPlatform.iOS>Helvetica-Black</OnPlatform.iOS>
      <OnPlatform.Android>Roboto-Black</OnPlatform.Android>
      <OnPlatform.WinPhone></OnPlatform.WinPhone>
    </OnPlatform>
  </Label.FontFamily>
</Label>
<Label Text="Light" TextColor="#000000">
  <Label.FontSize>
    <OnPlatform x:TypeArguments="x:Double"
                iOS="17"
                Android="16"
                WinPhone="16" />
  </Label.FontSize>
  <Label.FontFamily>
    <OnPlatform x:TypeArguments="x:String">
      <OnPlatform.iOS>Helvetica-Light</OnPlatform.iOS>
      <OnPlatform.Android>Roboto-Light</OnPlatform.Android>
      <OnPlatform.WinPhone></OnPlatform.WinPhone>
    </OnPlatform>
  </Label.FontFamily>
</Label>
<Label Text="Medium" TextColor="#000000" >
  <Label.FontSize>
    <OnPlatform x:TypeArguments="x:Double"
                iOS="17"
                Android="16"
                WinPhone="16" />
  </Label.FontSize>
  <Label.FontFamily>
    <OnPlatform x:TypeArguments="x:String">
      <OnPlatform.iOS>Helvetica-Medium</OnPlatform.iOS>
      <OnPlatform.Android>Roboto-Medium</OnPlatform.Android>
      <OnPlatform.WinPhone></OnPlatform.WinPhone>
    </OnPlatform>
  </Label.FontFamily>
</Label>
<Label Text="Bold"  TextColor="#000000">
  <Label.FontSize>
    <OnPlatform x:TypeArguments="x:Double"
                iOS="17"
                Android="16"
                WinPhone="16" />
  </Label.FontSize>
  <Label.FontFamily>
    <OnPlatform x:TypeArguments="x:String">
      <OnPlatform.iOS>Helvetica-Bold</OnPlatform.iOS>
      <OnPlatform.Android>Roboto-Bold</OnPlatform.Android>
      <OnPlatform.WinPhone></OnPlatform.WinPhone>
    </OnPlatform>
  </Label.FontFamily>
</Label>

However, the result in Android is unexpected. The FontFamily of the different Labels is not changed. They all look the same.

Android

The same code in iOS works as expected

enter image description here

My question is: How to get the Roboto-Light, Roboto-Medium and Roboto-Bold fonts in my Android app if following XAMARIN documentation does not work?

Pavel Pavlov
  • 697
  • 2
  • 9
  • 18

4 Answers4

4

Update:

I did not see that you were using API 18 / 4.3 the first time (in the title bar of your emulator), thought you were loading them as custom assets for older android versions. Since roboto is the default font since 4.1, you can use them as:

  • sans-serif
  • sans-serif-light
  • sans-serif-condensed
  • sans-serif-thin (4.2+)

Original:

https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/fonts/

Xamarin.Forms for Android does not currently expose the ability to set the font to a custom font file, so custom renderers are required. When writing the renderer for the Android platform, create a Typeface instance that references a custom font file that has been added to the Assets directory of the application (with Build Action: AndroidAsset).

[assembly: ExportRenderer (typeof (MyLabel), typeof (MyLabelRenderer))]
namespace WorkingWithFonts.Android {
    public class MyLabelRenderer : LabelRenderer {
        protected override void OnElementChanged (ElementChangedEventArgs<Label> e) {
            base.OnElementChanged (e);
            var label = (TextView)Control; // for example
            Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "SF Hollywood Hills.ttf");
            label.Typeface = font;
        }
    }
}
SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • Thank you for noting that sans-serif font family actually utilizes the Roboto font since Android 4.1. I have only one addition to your answer. Note that there is no sans-serif-bold (or something similar) font, unlike helvetika-bold. In order to set the font to bold I set the Label.FontAttributes property to Bold. This achieves my requirements. Or at least achieves them before the designer takes a look at the app :) – Pavel Pavlov Sep 23 '15 at 10:53
  • the first answer [here](http://stackoverflow.com/questions/12128331/how-to-change-fontfamily-of-textview-in-android) also confirms this statement. – Pavel Pavlov Sep 23 '15 at 11:06
  • @SushiHangover - The link you posted above now indicates that custom fonts are now available on Android. However, I'm not seeing my custom font being used on Android despite following the steps in the article. Do you know whether custom fonts are in fact still not supported in Android? – James Lavery Aug 11 '17 at 11:46
  • @JamesLavery Xamarin.Forms does now indeed support custom fonts on Android, the font naming is critical: https://developer.xamarin.com/guides/xamarin-forms/user-interface/text/fonts/#Android – SushiHangover Aug 11 '17 at 15:01
  • @SushiHangover - thanks. I've implemented according to that guide, but its not picking up the custom fonts. As you say, naming of the Font (_not_ the TTF file) is vital. There's a mismatch somewhere, which I need to get to the bottom of. – James Lavery Aug 11 '17 at 15:12
1

I did overwrite the default Renderer for all views I needed it for.

That way you can use XAML code like you intended to:

<Label FontFamily="Arial" Text="Hi there" />

Here is an example for Label.

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

            if ( !String.IsNullOrEmpty(Element.FontFamily) )
                Control.Typeface = Typeface.CreateFromAsset(Forms.Context.Assets, "Fonts/" + Element.FontFamily + ".otf");
        }
    }
}

Of course you need to map that to the location where you embedded the custom font. In my case Assets/Fonts/Arial.otf.

Florian
  • 465
  • 5
  • 17
0

Please use below render, to load custom font in label, please make sure that you will put your font file in fonts folder in assets folder of android project to define similar path for all platform

[assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
namespace MyApp.Droid.Renderer
{
    public class CustomLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
                if (!String.IsNullOrEmpty(e.NewElement.FontFamily))
                    Control.Typeface = Typeface.CreateFromAsset(Forms.Context.Assets, "Fonts/" + Element.FontFamily);
        }
    }
}

xaml of label control, please make sure that font file is available in font folder

<Label FontFamily="Roboto-Light.ttf" Text="Hi there" />
Ashish Patel
  • 226
  • 5
  • 8
0

2020 Update, Xamarin.Forms 4.5 now supports custom fonts embedded in one place (shared UI project) and exported via ExportFont attribute: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/fonts#use-a-custom-font - iOS, Android and UWP. For macOS and WPF you still have to go longer path as described below.

As of 2018, in Xamairn.Forms, there's no need for platform renderers. The steps are:

  1. Download TTF files and bundle them as resources with each platform project.
  2. Reference the fonts from within Xamarin.Forms shared project, taking into account the peculiarities of each platform (naming conventions for addressing resources and font families).
  3. Apply the fonts to Xamarin.Forms controls.

Here's detailed description on how to add and apply custom fonts in macOS, WPF and Android.

Maxim Saplin
  • 4,115
  • 38
  • 29