android – Custom Fonts with Support Library is not working on a real device-ThrowExceptions

Exception or error:

I have used custom font with Support Library API 26. I have created font-family using style and add style to my text view. I found that font is going to set in Preview during design, but not working in android real devices. Below is my code and I have also attached screenshot. Thanks in advance.

TextView:

<TextView
    android:id="@+id/card_number_text"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="111 5235 5563 8845"
    android:gravity="left"
    android:layout_marginRight="8dp"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_marginTop="8dp"
    style="@style/creditCardText"
    app:layout_constraintTop_toBottomOf="@+id/payableLayout"
    app:layout_constraintLeft_toLeftOf="@+id/payableLayout"
    app:layout_constraintHorizontal_bias="0.0" />

Style.xml:

<style name="creditCardText">
    <item name="android:textSize">@dimen/textSizeLarge</item>
    <item name="android:fontFamily">@font/font_roboto_medium</item>
    <item name="android:textColor">@color/color_card_number</item>
</style>

Font Family:

<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
    android:fontStyle="normal"
    android:fontWeight="400"
    android:font="@font/roboto_medium" />

build.gradle:

apply plugin: 'com.android.application'
buildscript {
    repositories {
    }
    dependencies {
   }
}

android {
    signingConfigs {
    }
   compileSdkVersion 26
   defaultConfig {
        applicationId "org.saifintex.skypaytrans"
        minSdkVersion 18
        targetSdkVersion 26
        vectorDrawables.useSupportLibrary = true
        versionCode 7
        multiDexEnabled true
        versionName "1.6"
        testInstrumentationRunner 
        "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
   }

lintOptions {
    abortOnError false        // true by default
    checkAllWarnings false
    checkReleaseBuilds false
    ignoreWarnings true       // false by default
    quiet true                // false by default
}

repositories {
    maven { url "https://jitpack.io" }
}
dexOptions {
    javaMaxHeapSize "4g"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

    }
}
externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}
packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
}
productFlavors {
}
sourceSets {
    main {
        assets.srcDirs = ['src/main/assets', 'src/main/assets/']
        java.srcDirs = ['src/main/java', 'src/main/java/fonts']
    }
  }
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', 
{
    exclude group: 'com.android.support', module: 'support-annotations'
})
compile "com.android.support:appcompat-v7:26.1.0"
compile "com.android.support:design:26.1.0"
compile "com.android.support:recyclerview-v7:26.1.0"
compile project(':tooltip')
compile project(':mylibrary')
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.j256.ormlite:ormlite-
android:${rootProject.ormliteAndroidVersion}"
compile "com.j256.ormlite:ormlite-core:${rootProject.ormliteCoreVersion}"
testCompile 'junit:junit:4.12'
compile 'com.afollestad.material-dialogs:core:0.9.4.2'
compile 'com.fasterxml.jackson.core:jackson-core:2.7.2'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.2'
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.android.volley:volley:1.0.0'
compile 'commons-codec:commons-codec:1.10'
compile 'com.android.support:design:26.1.0'
compile 'com.squareup.picasso:picasso:2.4.0'
compile 'com.google.firebase:firebase-messaging:11.0.1'
compile 'com.google.firebase:firebase-core:11.0.1'
compile 'com.android.support:cardview-v7:26.1.0'
compile 'com.android.support:support-v4:26.1.0'
compile 'com.wang.avi:library:2.1.3'
compile 'com.github.ayalma:ExpandableRecyclerView:0.2.0'
compile 'com.github.deano2390:MaterialShowcaseView:1.1.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.firebase:firebase-crash:11.0.1'
compile 'com.google.firebase:firebase-auth:11.0.1'
compile 'com.google.android.gms:play-services-analytics:11.0.1'
compile 'com.alimuzaffar.lib:pinentryedittext:1.3.1'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-
core:3.0.1'
testCompile 'junit:junit:4.12'
}

configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
    def requested = details.requested
    if (requested.group == 'com.android.support') {
        if (!requested.name.startsWith("multidex") && 
        !requested.name.startsWith("crash")) {
            details.useVersion '25.3.1'
        }
    }
}
}

apply plugin: 'com.google.gms.google-services'

Font resource dir:

enter image description here

Design preview: Here font is working

enter image description here

Android Device Screenshot: Here font is not working

enter image description here

How to solve:

Change your TextView to an android.support.v7.widget.AppCompatTextView.

See https://stackoverflow.com/a/45208134/332798

###

Requirement

  • 1) assets folder which has sub folder “/fonts”

  • 2) require custom fonts “.ttf” files in /fonts folder.

  • 3) enum

  • 4) attrs.xml file

  • 5) java class

  • 6) Usage


1)
create assets folder in

src/main/assets

2)
add custom fonts in

src/main/assets/fonts/

3) enum

import android.annotation.SuppressLint;
import android.content.Context;


@SuppressLint("StaticFieldLeak")
public enum Fonts {

OpenSans_Bold("OpenSans-Bold.ttf", 0),
OpenSans_BoldItalic("OpenSans-BoldItalic.ttf", 1),
OpenSans_CondBold("OpenSans-CondBold.ttf", 2),
OpenSans_CondLight("OpenSans-CondLight.ttf", 3),
OpenSans_CondLightItalic("OpenSans-CondLightItalic.ttf", 4),
OpenSans_ExtraBold("OpenSans-ExtraBold.ttf", 5),
OpenSans_ExtraBoldItalic("OpenSans-ExtraBoldItalic.ttf", 6),
OpenSans_Italic("OpenSans-Italic.ttf", 7),
OpenSans_Light("OpenSans-Light.ttf", 8),
OpenSans_LightItalic("OpenSans-LightItalic.ttf", 9),
OpenSans_Regular("OpenSans-Regular.ttf", 10),
OpenSans_Semibold("OpenSans-Semibold.ttf", 11),
OpenSans_SemiboldItalic("OpenSans-SemiboldItalic.ttf", 12),

AudioWide_Regular("Audiowide_Regular.ttf", 13);

String stringValue;
int value;
Context context;

Fonts(Context context) {
    this.context = context;
}

Fonts(String toString, int value) {
    stringValue = toString;
    this.value = value;
}

@Override
public String toString() {
    return "fonts/" + stringValue;
}

}

4)
attrs.xml file

create attrs.xml in res/values folder

<resources>
<declare-styleable name="FontTextView">

    <attr name="customFont" format="enum">
        <enum name="OpenSans_Bold" value="0" />
        <enum name="OpenSans_BoldItalic" value="1" />
        <enum name="OpenSans_CondBold" value="2" />
        <enum name="OpenSans_CondLight" value="3" />
        <enum name="OpenSans_CondLightItalic" value="4" />
        <enum name="OpenSans_ExtraBold" value="5" />
        <enum name="OpenSans_ExtraBoldItalic" value="6" />
        <enum name="OpenSans_Italic" value="7" />
        <enum name="OpenSans_Light" value="8" />
        <enum name="OpenSans_LightItalic" value="9" />
        <enum name="OpenSans_Regular" value="10" />
        <enum name="OpenSans_Semibold" value="11" />
        <enum name="OpenSans_SemiboldItalic" value="12" />
        <enum name="Audiowide_Regular" value="13" />

    </attr>

</declare-styleable>


5)
FontTextView.java

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import com.example.Fonts;
import com.example.R;

@SuppressLint("AppCompatCustomView")
public class FontTextView extends TextView {

public FontTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs);
}

public FontTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
}

public FontTextView(Context context) {
    super(context);
}

private void init(Context context, AttributeSet attrs) {

    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FontTextView, 0, 0);

    String fontText = a.getString(R.styleable.FontTextView_customFont);

    if (fontText != null) {
        switch (fontText) {
            case "0":
                fontText = Fonts.OpenSans_Bold.toString();
                break;
            case "1":
                fontText = Fonts.OpenSans_BoldItalic.toString();
                break;
            case "2":
                fontText = Fonts.OpenSans_CondBold.toString();
                break;
            case "3":
                fontText = Fonts.OpenSans_CondLight.toString();
                break;
            case "4":
                fontText = Fonts.OpenSans_CondLightItalic.toString();
                break;
            case "5":
                fontText = Fonts.OpenSans_ExtraBold.toString();
                break;
            case "6":
                fontText = Fonts.OpenSans_ExtraBoldItalic.toString();
                break;
            case "7":
                fontText = Fonts.OpenSans_Italic.toString();
                break;
            case "8":
                fontText = Fonts.OpenSans_Light.toString();
                break;
            case "9":
                fontText = Fonts.OpenSans_LightItalic.toString();
                break;
            case "10":
                fontText = Fonts.OpenSans_Regular.toString();
                break;
            case "11":
                fontText = Fonts.OpenSans_Semibold.toString();
                break;
            case "13":
                fontText = Fonts.AudioWide_Regular.toString();
                break;
            case "12":
                fontText = Fonts.OpenSans_SemiboldItalic.toString();
                break;
            default:
                fontText = Fonts.OpenSans_Regular.toString();
                break;
        }

        Log.e("String", fontText);
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), fontText);

        setTypeface(tf);
    }
    a.recycle();
}

}

6)
Usage

    <com.example.FontTextView
         android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10sp"
        android:text="this is custom font"
        android:textSize="20sp"
        app:customFont="OpenSans_Semibold" />

add below namespace to the top parents Layout of xml file
xmlns:app=”http://schemas.android.com/apk/res-auto”

reference by :

"Android Custom TypeFace fontFamily "

click here

with this, you can easily add any font in android.

###

A bit late to the party, but I’ve encountered an issue with using fontFamily in FragmentActivities. In those activities the font is not correctly shown. If you let your activity extend from AppCompatActivity (which extends FragmentActivity) than the font is correctly shown.

###

For the android support lib below api 26 you can use this:

create class TypefaceUtil.java and add code below

public class TypefaceUtil {
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {
        }
    }
}

… and in your application class that extends Application class add this:

 @Override
    public void onCreate() {
        super.onCreate();

        TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/myfont.ttf");
    }

… android add this class to manifest.xml

android:name=".MyApplication"

… and at the end add this line in you style:

<item name="android:typeface">serif</item>

but this is not working with support library api 26 and higher
for this you can use this version

  1. create a folder named font in res folder
  2. put your font in this folder
  3. create and xml file(font resource file)(myfont.xml) and add this code:

    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/font"
        app:fontStyle="normal" app:fontWeight="400" app:font="@font/font"/>
    
    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/font"
        app:fontStyle="italic" app:fontWeight="400" app:font="@font/font" />
    

… and now add this line in the style code of your app:

<item name="android:fontFamily">@font/myfont</item>

I hope this works for you.

###

I spent hours trying to figure out why the font wasn’t working. I was trying to migrate from Calligraphy library and you have to disable the default font setup in Application class.

setDefaultFontPath(app.getString(R.string.font_path_medium))

Replace the default font setup with this.

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
    <item name="android:fontFamily">your_front</item>
</style>

<style name="RobotoButtonStyle" parent="android:Widget.Button">
    <item name="android:fontFamily">your_font</item>
</style>

###

If you are using butterknife view injection for binding your custom text or button view, you should override onFinishInflate() method in custom view class.
For example:

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    Typeface font_type = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontStyle);
    this.setTypeface(font_type);
}

Leave a Reply

Your email address will not be published. Required fields are marked *