Android Xamarin: Custom fonts made easy

Using custom fonts on Android is not the most straightforward task. The Android layout XMLs does not offer any way to add custom fonts by default. So, we need to either create custom TextViews or set the font in code. Both methods have significant drawbacks. Subclassing is restrictive, and if you already have a reasonable project size, then subclassing becomes prohibitive. Setting the font from code is error prone and slow; editing the font means Android needs to remeasure the view, at worst this may mean that Android will remeasure every other view on the screen.

Is all hope lost? No. Calligraphy solves both the custom font problem in a way that means we don’t need either subclassing or editing the font after view creation. Calligraphy adds a new XML tag that allows you to specify the custom font at design time. So, now we don’t need subclassing or remember to set the typeface on every TextView after view creation.

First, install the Xamarin binding for Calligraphy from NuGet.

Install-Package CallygraphyXamarin

Next, we need some custom fonts. I’m just going to use the Roboto font from Google’s Material design. Roboto is the default for Lollipop and above, but we want a consistent look for pre-lollipop users as well. Now we have some custom fonts lets add them to our project. Fonts need to be in the Assets folder so we will just add them into a fonts folder in Assets. Lastly, we need to set the build action on our new fonts to AndroidAsset; otherwise Android will not include them.

https://material.google.com/resources/roboto-noto-fonts.html

Great, let’s go right? Not just yet. There is a little Boilerplate we need to weld onto our project before we can start using our excellent Material design fonts. I promise it’s not much.

Setup Calligraphy

In your Activity base class add the following

protected override void AttachBaseContext(Context newBase)
{
base.AttachBaseContext(CalligraphyContextWrapper.Wrap(newBase));
}

If you don’t have a common base class, well congratulations now you do; Calligraphy needs an Activity context to work. So, we can’t just use the Android Application context since it’s a supper class of activity.

Ok, I promise that we have finished shaving the Yak.

http://s.quickmeme.com/img/25/25c17af0b98cf8e06ad2550b2efd107a67990dd1938942ab2f11de68a9800652.jpg

Using a custom font

Just add the xml attribute fontPath and your done.

<TextView
fontPath=”fonts/Roboto-Bold.ttf”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Calligraphy makes fonts easy” />

The attribute fontPath does not have a prefix. So, if you do get a warning saying there is a missing prefix you can add this to the TextView or its parent. It will still compile and work regardless.

tools:ignore=”MissingPrefix”

Default application font

You can also set an Application wide default configuration that will apply a default font to ever TextView. Here we need to sub class the Android Application Object

     [Application]
public class MyApplication : Application
{
/// <inheritdoc />
public MyApplication(
IntPtr javaReference,
JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}

/// <inheritdoc />
public override void OnCreate()
{
base.OnCreate();
CalligraphyConfig.InitDefault(
new CalligraphyConfig.Builder()
.SetDefaultFontPath("fonts/Roboto-Bold.ttf")
.SetFontAttrId(Resource.Attribute.fontPath)
.Build()
);
}
}

If you get a error about the Resource.Attribute.fontPath don’t worry. It should be generated when you build. If it’s not, a clean-n-build should work.

Limits

Calligraphy is not magic there are a few Limits

* Calligraphy only works when inflating views from XML.
* Xamarin.Forms creates views in by parsing XAML at runtime or compile time; Calligraphy depends on the Android layout creation to inject the fonts

Calligraphy still works in Xamarin Forms, but you still need to make a custom renderer. Calligraphy also comes with a few Android Text utils like CalligraphyTypefaceSpan that makes setting multiple fonts on a TextView simpler.

Consultation

Calligraphy is an excellent way to add custom fonts for both Xamarin and vanilla Android applications. I only covered the basic setup and usage here, but there is so much more to Calligraphy.

I would suggest you check out https://github.com/mikescandy/Calligraphy-xamarin for more details. Also, the Java Calligraphy project page https://github.com/chrisjenx/Calligraphy there you will find more examples, issues, and documentation.

I’ve also setup a basic project here https://github.com/marukami/CallygraphyXamarinSample