2
votes

In order to use custom fonts in an android app there seem to be two approaches:

  1. Classic way: place TTF or OTF files in the /assets/fonts directory and then build a Typeface with Typeface.createFromAsset(getAssets(), "fonts/custom.ttf").
  2. Natively since API 26, or with AppCompat since API 16: create an XML font family by placing lowercased TTF/OTF files in res/font folder and then reference them directly in XML layouts with android:fontFamily="@font/custom", or access them programatically with ResourcesCompat.getFont(this, R.font.custom).

What are the key differences to keep in mind between font resources and assets?

Specifically, are they rendered in the same way, and is any of them faster or more efficient in terms of performance?

Can it be assumed that font resources are only suitable for fonts that come pre-packaged in the APK, while font assets are more flexible since you can create a Typeface from an arbitrary file inside or outside the APK?

Update: After a bit of experimentation it looks like font resources are the only way to set custom fonts in AppWidget TextViews without having to manually paint them as bitmaps but that requires the device to actually run API 26 (using the Support Library does not help in this specific case).

1
Font resources are supported since API 26 natively OR on all versions of Android with the help of AppCompat. That's the point of AppCompat - have the new stuff be able to run on older devices. Where did you get this Apart from XML font resources being supported only from API 26 upwards *and* requiring the AppCompat dependency?Eugen Pechanec
@EugenPechanec: Yes, my wording was confusing; thanks for spotting it, fixed.ccpizza
When using the support library, to correctly load a font in an XML layout file you must use the app namespace: app:fontFamily="@font/custom". Source: developer.android.com/guide/topics/ui/look-and-feel/…Domenico

1 Answers

3
votes

Specifically, are they rendered in the same way, and is any of them faster or more efficient in terms of performance?

ResourcesCompat.getFont works like this:

  1. Check in-memory cache if we already resolved a font resource ID to Typeface. If we have a hit, we're done.
  2. Copy the resource to a disk file.
  3. Create Typeface from the file using Typerface.createFromFile and cache it.

That's true for fonts bundled in the APK. I won't go into how downloadable fonts work. You can explore that in the docs or in the source.

Both approaches work the same. They create a Typeface object from a source.

One key difference: If you're directly using Typeface API, you're responsible for caching. You don't want to load the same font multiple times because each Typeface instance takes up loads of memory.

Historically, I was using this code from Calligraphy to take care of caching when loading typefaces from assets.

After a bit of experimentation it looks like font resources are the only way to set custom fonts in AppWidget TextViews [...]

Looks like you're right. Notifications and widgets (anything that uses RemoteViews) can only use natively available resources and attributes on views.

See also: How to use a custom typeface in a widget?