53

Is it possible to set the font for all the TextViews in a activity? I can set the font for a single textView by using:

    TextView tv=(TextView)findViewById(R.id.textView1); 
    Typeface face=Typeface.createFromAsset(getAssets(), "font.ttf"); 
    tv.setTypeface(face);

But I would like to change all the textViews at once, instead of setting it manually for every textView, any info would be appreciated!

William L.
  • 3,846
  • 9
  • 53
  • 72

8 Answers8

92

Solution1:: Just call these method by passing parent view as argument.

private 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(Typeface.createFromAsset(context.getAssets(), "font.ttf"));
        }
    } catch (Exception e) {
 }
 }

Solution2:: you can subclass the TextView class with your custom font and use it instead of textview.

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();
    }

    private void init() {
        if (!isInEditMode()) {
            Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "font.ttf");
            setTypeface(tf);
        }
    }

}
Shankar Agarwal
  • 34,573
  • 7
  • 66
  • 64
  • 1
    Both solutions work, in fact. But the first is really heavy and every time you add a TextView on a Layout, you must recall the method... The second is the best, but it implies a whole refactoring of the project (note that if the project is not huge, it can take a few minutes... – ChristopheCVB May 26 '12 at 13:54
  • @ChristopheCVB exactly but i have two solution and him decide what he wanna to do and the second is best solution – Shankar Agarwal May 26 '12 at 13:56
  • Yes, of course, I really agree with you. Thanks for these solutions ! – ChristopheCVB May 26 '12 at 14:16
  • 3
    Improvement to method 1 would be to create the Typeface once (Typeface.createFromAsset) and save it as a field in the class, instead of creating it for each TextView. – Fraggle Sep 26 '13 at 23:13
  • is it good to use this library http://mycode.restservices.org/2013/10/01/excellent-library-for-custom-fonts-in-android/ in terms of performance and all? – Ram Patra Feb 17 '14 at 18:21
  • Works with textviews, but webView(not work) or spinners(not work) ? –  Jul 03 '15 at 09:35
  • That "catch all" is bad – Oded Breiner Jan 19 '16 at 08:28
  • How is the performance when calling `Typeface.createFromAsset` so often? I mean when i have ~20 TextViews in an activity. Will it be still ok? – Philip Giuliani May 31 '16 at 13:11
  • How will I use it if I set my view in the layout as textView before ? – Recomer Jun 20 '16 at 08:26
8

The one from my personal collection:

private void setFontForContainer(ViewGroup contentLayout) {
    for (int i=0; i < contentLayout.getChildCount(); i++) {
        View view = contentLayout.getChildAt(i);
        if (view instanceof TextView)
            ((TextView)view).setTypeface(yourFont);
        else if (view instanceof ViewGroup)
            setFontForContainer((ViewGroup) view);
    }
}
Red Hot Chili Coder
  • 1,218
  • 1
  • 10
  • 19
3

If you are looking for a more general programatic solution, I created a static class that can be used to set the Typeface of an entire view (Activity UI). Note that I am working with Mono (C#) but you can implement it easily using Java.

You can pass this class a layout or a specific view that you want to customize. If you want to be super efficient you could implement it using the Singleton pattern.

public static class AndroidTypefaceUtility 
{
    static AndroidTypefaceUtility()
    {
    }
    //Refer to the code block beneath this one, to see how to create a typeface.
    public static void SetTypefaceOfView(View view, Typeface customTypeface)
    {
    if (customTypeface != null && view != null)
    {
            try
            {
                if (view is TextView)
                    (view as TextView).Typeface = customTypeface;
                else if (view is Button)
                    (view as Button).Typeface = customTypeface;
                else if (view is EditText)
                    (view as EditText).Typeface = customTypeface;
                else if (view is ViewGroup)
                    SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
                else
                    Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
                    throw ex;
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
            }
        }

        public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
        {
            if (customTypeface != null && layout != null)
            {
                for (int i = 0; i < layout.ChildCount; i++)
                {
                    SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
            }
        }

    }

In your activity you will need to create a Typeface object. I create mine in the OnCreate() using a .ttf file placed in my Resources/Assets/ directory. Make sure that the file is marked as an Android Asset in its' properties.

protected override void OnCreate(Bundle bundle)
{               
    ...
    LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
    Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
    AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}
JCKortlang
  • 227
  • 2
  • 9
2

Best answers

1. Setting custom font for one textView

Typeface typeface = Typeface.createFromAsset(getContext().getAssets(), "Fonts/FontName.ttf");
textView.setTypeface (typeface);

2. Setting custom font for all textViews

Create a JavaClass like below

public class CustomFont extends android.support.v7.widget.AppCompatTextView {

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

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

    public CustomFont(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
            Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/FontName.ttf");
            setTypeface(tf);
    }
}

And in your xml page

<packageName.javaClassName>

...

/>

=>

    <com.mahdi.hossaini.app1.CustomFont
    android:id="@+id/TextView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:text="KEEP IT SIMPLE"
    android:textAlignment="center" />
Mahdi Hossaini
  • 111
  • 1
  • 4
1

Extending Agarwal's answer... you can set regular, bold, italic, etc by switching the style of your TextView.

import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class TextViewAsap extends TextView {

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

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

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

    private void init() {
        if (!isInEditMode()) {
            Typeface tf = Typeface.DEFAULT;

            switch (getTypeface().getStyle()) {
                case Typeface.BOLD:
                    tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Bold.ttf");
                    break;

                case Typeface.ITALIC:
                    tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Italic.ttf");
                    break;

                case Typeface.BOLD_ITALIC:
                    tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Italic.ttf");
                    break;

                default:
                    tf = Typeface.createFromAsset(getContext().getAssets(), "Fonts/Asap-Regular.ttf");
                    break;
            }

            setTypeface(tf);
        }
    }

}

You can create your Assets folder like this: Create Assets

And your Assets folder should look like this:

enter image description here

Finally your TextView in xml should be a view of type TextViewAsap. Now it can use any style you coded...

<com.example.project.TextViewAsap
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Example Text"
                android:textStyle="bold"/>
dianakarenms
  • 2,609
  • 1
  • 22
  • 22
1

You can use the Calligraphy library which is available here:
Android Calligraphy Library

Dariush Salami
  • 145
  • 1
  • 6
0

example of more "generic" way with use of reflection:

** it's presenting a idea of involving viewgroup children's method setTextSize(int,float) but you can adopt it as in the case of your question to setTypeFace()

 /**
 * change text size of view group children for given class
 * @param v - view group ( for example Layout/widget)
 * @param clazz  - class to override ( for example EditText, TextView )
 * @param newSize - new font size
 */
public static void overrideTextSize(final View v, Class<?> clazz, float newSize) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideTextSize(child, clazz, newSize);
            }
        } else if (clazz.isAssignableFrom(v.getClass())) {
            /** create array for params */
            Class<?>[] paramTypes = new Class[2];
            /** set param array */
            paramTypes[0] = int.class;  // unit
            paramTypes[1] = float.class; // size
            /** get method for given name and parameters list */
            Method method = v.getClass().getMethod("setTextSize",paramTypes);
            /** create array for arguments */
            Object arglist[] = new Object[2];
            /** set arguments array */
            arglist[0] = TypedValue.COMPLEX_UNIT_SP;
            arglist[1] = newSize;
            /** invoke method with arguments */
            method.invoke(v,arglist);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

CAUTION:

using reflection should be very careful. Reflection class it's very "exceptional"

  • for example, you should check for the presence of annotations to prevent different kinds of problems. In the case of method SetTextSize () It is desirable to check the annotations android.view.RemotableViewMethod
ceph3us
  • 7,326
  • 3
  • 36
  • 43
0

You can use style inheritance.

Have every one of your TextViews in the activity declare a style via android:textAppearence, instead of manually android:typeface.

Then, have each one's style inherit the activity style, like so:

<TextView ...
      android:textAppearance="@style/item_name"/>
<TextView ...
      android:textAppearance="@style/item_details"/>

in style.xml:

<style name="ActivityStyle">
    <item name="android:fontFamily">@font/font</item>
</style>
<style name="item_name" parent="ActivityStyle">
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">20sp</item>
</style>
<style name="item_details" parent="ActivityStyle">
    <item name="android:textSize">15sp</item>
</style>
f.khantsis
  • 3,256
  • 5
  • 50
  • 67