Valgaal
Valgaal

Reputation: 946

Why fonts don't apply if I create TextView from code (on specific devices)

I changed font in my project for custom one. It's working ok on emulator and many devices, but on some devices it doesn't work in some cases, for example, when I create TextView from code.

I have a sample project that demonstrate this problem.

Here my style file

<resources>
    <style name="TextStyle.Caption" parent="TextAppearance.AppCompat.Caption">
        <item name="android:textSize">12sp</item>
        <item name="android:fontFamily">@font/eesti_pro_display_bold</item>
        <item name="android:letterSpacing">0.03</item>
    </style>
</resources>

This is my xml. Here I have TextView with textAppearance

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textAppearance="@style/TextStyle.Caption"/>

</androidx.constraintlayout.widget.ConstraintLayout>

My Activity where I create another TextView

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val layout: ConstraintLayout = findViewById(R.id.container)
        createItemTitleTextView(this.baseContext).apply {
            layout.addView(this)
            text = "Hello World from code!"
        }
    }
}

private fun createItemTitleTextView(context: Context) = TextView(context).apply {
    TextViewCompat.setTextAppearance(this, R.style.TextStyle_Caption)
}

Result on emulator(Expected result):

Emulator result

Result on Samsung Galaxy J5. Italic font is Galaxy system font. Note that my font is working from xml, but not from code

enter image description here

EDIT

I know that i can use setTypeface and everything is working as expected, but I want to know why setTextAppearance doesn't work. Because I just want to change my styles file, not the whole project and add setTypeface to every TextView from code

Upvotes: 5

Views: 987

Answers (2)

Valgaal
Valgaal

Reputation: 946

TextViewCompat.setTextAppearance(tv, R.style.TextStyle_Caption) doesn't work because I create TextView. However, I need to create AppCompatTextView and everything works as expected

Upvotes: 3

Kishita Variya
Kishita Variya

Reputation: 810

Before Android 8.0, fontFamily only supports default values:

android:fontFamily="sans-serif"           // roboto regular  
android:fontFamily="sans-serif-light"     // roboto light  
android:fontFamily="sans-serif-condensed" // roboto condensed  
android:fontFamily="sans-serif-thin"      // roboto thin (android 4.2)  
android:fontFamily="sans-serif-medium"    // roboto medium (android 5.0)

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

For Custom Fonts, you need to download ttf file and use it as follows:

  Typeface typeface = Utils.getTypeface(context, textStyle);
    if (typeface != null) setTypeface(typeface);

and the function in Utils file is:

public static Typeface getTypeface(Context context, int textStyle) {
    try {
        String font = "fonts/font-file-name.ttf"
        Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
        return myTypeface;
    } catch (Exception e) {
        Log.d(Constants.TAG, "OpenSansTextView init: ");
        e.printStackTrace();
    }
    return null;
}

The Location of my ttf file:

app\src\main\assets\fonts\font-file-name.ttf

EDIT (Alternate Solution):

If you already have too many TextViews which you cannot add "setTypeface" everywhere in java, Then, just press Ctrl + Shift + R and replace <TextView with <com.your.package.app.MyTextView. you can create your custom TextView as:

package com.your.package.app;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;


public class MyTextView extends android.support.v7.widget.AppCompatTextView {
    Context context;
    Integer textStyle = 0;
    String textOS;

    public MyTextView(Context context) {
        super(context);
        this.context = context;
        init(null);
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init(attrs);
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        try {
             String font = "fonts/font-file-name.ttf"
             Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
             if (typeface != null) setTypeface(typeface);
        } catch (Exception e) {
            Log.d(Constants.TAG, "MyTextView init: ");
            e.printStackTrace();
        }
    }

}

Upvotes: 1

Related Questions