Alin Alin - 6 months ago 18
Android Question

Custom Fonts and Custom Textview on Android

From an application I need to develop, I've received a specific font that has many files like FontName-Regular, FontName-Bold, FontName-it. I need to use it in all the textviews in the application. First I thought it was an easy task. Look over SO and found a very nice thread:here

So first I did like:

public static void overrideFonts(final Context context, final View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
overrideFonts(context, child);
}
} else if (v instanceof TextView) {
((TextView)v).setTypeface(FONT_REGULAR);
}
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}


And called this method during onCreate in my activity. Every textView in my app was showing that font and boy, was I happy for getting away so easy. Until I got to a screen where some textviews required Bold as
Style
(
android:textStyle="bold"
). Then I realized that this solution does not provide me with possibility to load the Font-Bold.ttf from assets.

Than looked further and saw a nice custom TextView implementation, in the same SO question:

public class MyTextView extends TextView {

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

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

public MyTextView(Context context) {
super(context);
init();
}

public void init() {

Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font/chiller.ttf");
setTypeface(tf ,1);

}
}


This looks even better. My question is: how can I detect on
init()
if my control has Style set to Bold or not so I can assign the requested TypeFace ?

Thank you for your time.

LE. Following the example below, I've updated my class as:

public class MyTextView extends TextView {

Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), Constants.FONT_REGULAR);
Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), Constants.FONT_BOLD);

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

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

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

public void setTypeface(Typeface tf, int style) {
if (style == Typeface.BOLD) {
super.setTypeface(boldTypeface/*, -1*/);
} else {
super.setTypeface(normalTypeface/*, -1*/);
}
}
}


Well If I debug, the app goes in setTypeFace and it seems to apply the bold one, but on my layout I can't see any change, not bold. No matter what font I use, no changes are done in my TextView and is displayed with the default android font. I wonder why ?

I have summed everything on a blog post here on my blog maybe it will help someone.

Answer

The constructor of TextView calls setTypeface(Typeface tf, int style) with the style parameter retrieved from the XML attribute android:textStyle. So, if you want to intercept this call to force your own typeface you can override this method as follow:

public void setTypeface(Typeface tf, int style) {
    Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_normal_font.ttf");
    Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_bold_font.ttf");

    if (style == Typeface.BOLD) {
        super.setTypeface(boldTypeface/*, -1*/);
    } else {
        super.setTypeface(normalTypeface/*, -1*/);
    }
}