Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using custom font for all text within app not working with Lollipop

The problem I am having is specific to Android 5.0 (including 5.0.1/5.0.2) on both phones and my tablet (Nexus 9). Earlier versions of Android work fine.

In my app I want to set a global font that overrides all text. The way I've been accomplishing this prior to 5.0 was using this method. This method of font overriding doesn't seem work on any version of Lollipop that I've tried but works perfectly in 2.x and 4.x. I'm also running this code in a BaseApplication class I have so the font is only initialized in the onCreate() of my BaseApplication.

It seems like this was a bug in the Developer Preview and reported here. I tried the fix suggested in post #16 to use the TTX Tool to convert your font file to .ttx and back to .otf but that didn't seem to fix the issue like it did for others. I also verified that my .otf font file is valid and isn't corrupted according to the OTS sanitizer tool.

I also have a custom TextView that I can set the font via the layout. An example would be:

<com.myapp.widgets.CustomTextView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="Testing text view font"
     myapp:fontName="my-font.otf" />

This CustomTextView uses setTypeface(typeFace) in the view's initialization to set the font. This works on 5.0 but isn't really a possible solution I can use since I would need to go through every layout and change TextView, EditText, etc to use the CustomTextView and doesn't work with Dialog text wither.

So setting a single TextView's font with my CustomTextView class works fine in all version of Android, just not setting it globally.

I've also looked through the styles source code to see if I can find any differences between the Material and Holo theme but nothing seemed like it would change the android:typeface. My initial thoughts with this were that the Material theme somehow is overriding the android:typeface attribute over my app theme but I wasn't able to find anything.

Any thoughts or input would be greatly appreciated, thanks!

like image 451
wchristiansen Avatar asked Mar 17 '23 10:03

wchristiansen


2 Answers

What I ended up doing to resolve this was use Calligraphy to set global fonts. https://github.com/chrisjenx/Calligraphy

Simply just add this code to the onCreate() of my custom Application class.

 // Custom font file located in the "assets/fonts/"
 String customFont = "Helvetica-Neue.otf";
 CalligraphyConfig.initDefault(
     new CalligraphyConfig.Builder()
     .setDefaultFontPath("fonts/" + customFont)
     .build()
 );

Update as of SDK v26

If you are only supporting v26+ or using the support library, there now us a built in way to handle custom fonts throughout your app. Here is a link to the Android Developers page. The basics are as follows:

1) Add your custom font (.otf or .ttf) to your res/font directory

2) Create a new font family with the fonts files you added: res/font/your_font_family.xml

<?xml version="1.0" encoding="utf-8"?>
<font-family
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!-- Normal -->
    <font
        android:font="@font/your_font_normal"
        android:fontStyle="normal"
        android:fontWeight="400"
        app:font="@font/your_font_normal"
        app:fontStyle="normal"
        app:fontWeight="400"/>
    <!-- Italic -->
    <font
        android:font="@font/your_font_italic"
        android:fontStyle="italic"
        android:fontWeight="400"
        app:font="@font/your_font_italic"
        app:fontStyle="italic"
        app:fontWeight="400"/>
    <!-- Bold -->
    <font
        android:font="@font/your_font_bold"
        android:fontStyle="normal"
        android:fontWeight="700"
        app:font="@font/your_font_bold"
        app:fontStyle="normal"
        app:fontWeight="700"/>
</font-family>

3) If you want to apply this font app-wide, create a style in your base theme style, usually located in: res/styles/style.xml

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Other app styling -->
    <item name="android:fontFamily">@font/your_font_family</item>
</style>

4) If you only want to apply the font to a single or handful of views you can use the android:fontFamily attribute in XML or use:

val typeface = ResourcesCompat.getFont(context, R.font.your_font_family)
textView.typeface = typeface

This all seems to work on all versions of Android that I've tested.

like image 186
wchristiansen Avatar answered Mar 19 '23 23:03

wchristiansen


i was also following this method which worked until Android 4.4 like a charm, but didn't work in Lolipop. In my case, the problem was solved (after some googling) by converting the ".ttf" font file to ".otf" I used this web for the conversion. Now it works in all versions. Hope it helps

like image 34
Hugo Avatar answered Mar 20 '23 00:03

Hugo