Custom Fonts with Support Library is not working on a real device
Asked Answered
T

7

27

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

Traject answered 13/11, 2017 at 11:14 Comment(5)
did you apply the style to your textview? Check the xmlCastigate
I see the same problem. I tried referencing the font directly (instead of via a font-family), and also tried both otf and ttf files. It works in Android Studio preview, but not on an API 24 device.Tb
did you find any solution ?Prebend
@Yogesh did you find any solutionUnaccountedfor
@Yogesh any soloution??Later
T
47

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

See https://mcmap.net/q/363009/-using-font-in-xml-in-api-lt-26

Tb answered 9/1, 2018 at 22:19 Comment(3)
I've spent the last 8 hours trying to work out why some of my views were using my font and some weren't. Your answer lead me to the explanation - the description of AppCompatTextView specifically says "You should only need to manually use this class when writing custom views." and that's exactly what I'm doing! Thanks so much for saving my sanity!Sanfo
Thanks a lot! This also worked for me. In my case I was creating programmatically CheckedTextView and the default font wasn't working, changing to AppCompatCheckedTextView did the trick! :)Identity
Weird thing is that I need AppCompat even for Android 7.1.1. I'm not sure if it's related to AndroidX, I have already my project to it. Anyways, it worked, thanks!Davena
T
5

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>
Tether answered 16/10, 2018 at 16:2 Comment(0)
A
3

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.

Abdullah answered 13/11, 2017 at 11:19 Comment(2)
Thanks for your quick response. But I want to implement custom font as per Android O standard using support Design- developer.android.com/guide/topics/ui/look-and-feel/…Traject
@YogeshSrivastava thanks, but for this, I've not used this O feature yet. but I'll soon.Abdullah
A
3

Based on a similar issue I had, while also using the support library, I noticed this in the documentation:

Note: When you declare font families in XML layout through the support library, use the app namespace to ensure your fonts load.

So I had a look and updated the fontFamily attribute to use app: instead of android, so in your case:

<item name="app:fontFamily">@font/font_roboto_medium</item>

instead of:

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

Hope that helps! Seems to be a weird implementation of the support library causing the confusion here.

https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml#using-support-lib

Avidity answered 10/2, 2021 at 19:31 Comment(2)
This was the case for me. Thank you!Mader
It didn't work for me. Android Studio gave me an error Cannot resolve symbol 'app:fontFamily'. And if I just ignore the error and build anyway, I get a build error AAPT: error: style attribute 'app:attr/fontFamily' not found. Is there some kind of namespace declaration I need to add to my styles.xml to get this to work?Mundy
F
2

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.

Feldspar answered 12/7, 2018 at 12:52 Comment(0)
E
1

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);
}
Em answered 25/12, 2018 at 7:32 Comment(0)
B
0

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.

Billion answered 1/1, 2018 at 20:16 Comment(2)
oh, that simple! :-)Landed
your answer is not related to support library! see developer.android.com/guide/topics/ui/look-and-feel/…Later

© 2022 - 2024 — McMap. All rights reserved.