By DrDefrost

2010-03-04 01:13:15 8 Comments

I'm trying to define a GUI layout using XML files in Android. As far as I can find out, there is no way to specify that your widgets should use a custom font (e.g. one you've placed in assets/font/) in XML files and you can only use the system installed fonts.

I know that, in the Java code, I could change the font of each widget manually using unique IDs. Alternatively, I could iterate over all the widgets in Java to make this change, but this would probably be very slow.

What other options do I have? Is there any better ways to making widgets that have a custom look? I don't particularly want to have to manually change the font for every new widget I add.


@Vic 2019-02-09 08:41:29

It may be useful to know that starting from Android 8.0 (API level 26) you can use a custom font in XML.

You can apply a custom font to the entire application in the following way.

  1. Put the font in the folder res/font.

  2. In res/values/styles.xml use it in the application theme. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>

@duggu 2018-02-06 11:34:08

You can make easily custom textview class :-

So what you need to do first, make Custom textview class which extended with AppCompatTextView.

public class CustomTextView extends AppCompatTextView {
    private int mFont = FontUtils.FONTS_NORMAL;
    boolean fontApplied;

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

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

    public CustomTextView(Context context) {
        init(null, context);

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "", "Lato-Regular.ttf",
            Typeface typeface = getTypeface();
            int typefaceStyle = Typeface.NORMAL;
            if (typeface != null) {
                typefaceStyle = typeface.getStyle();
            if (mFont > FontUtils.FONTS) {
                typefaceStyle = mFont;
            FontUtils.applyFont(this, typefaceStyle);
            fontApplied = true;

Now , every time Custom text view call and we will get int value from attribute int fontValue = attrs.getAttributeIntValue("","Lato-Regular.ttf",-1).


We can also get getTypeface() from view which we set in our xml (android:textStyle="bold|normal|italic"). So do what ever you want to do.

Now, we make FontUtils for set any .ttf font into our view.

public class FontUtils {

    public static final int FONTS = 1;
    public static final int FONTS_NORMAL = 2;
    public static final int FONTS_BOLD = 3;
    public static final int FONTS_BOLD1 = 4;

    private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

    static Typeface getFonts(Context context, String name) {
        Typeface typeface = TYPEFACE.get(name);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(context.getAssets(), name);
            TYPEFACE.put(name, typeface);
        return typeface;

    public static void applyFont(TextView tv, int typefaceStyle) {

        Context cxt = tv.getContext();
        Typeface typeface;

        if(typefaceStyle == Typeface.BOLD_ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
        } else if (typefaceStyle == Typeface.ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
        } else {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        if (typeface != null) {

@Rasoul Miri 2017-08-30 12:32:27

There are two ways to customize fonts :

!!! my custom font in assets/fonts/iran_sans.ttf

Way 1 : Refrection Typeface.class ||| best way

call FontsOverride.setDefaultFont() in class extends Application, This code will cause all software fonts to be changed, even Toasts fonts

public class AppController extends Application {

    public void onCreate() {

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");


public class FontsOverride {

    public static void setDefaultFont(Context context, String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(), fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);

    private static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
        } catch (IllegalAccessException e) {

Way 2: use setTypeface

for special view just call setTypeface() to change font.

public class CTextView extends TextView {

    public CTextView(Context context) {

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())

        // use setTypeface for change font this view


public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                return null;
            fontCache.put(fontName, tf);
        return tf;


@Criss 2020-02-12 00:33:34

is it working on android 26 ?

@jeevan s 2017-03-28 05:32:01

The best way to do it From Android O preview release is this way
1.)Right-click the res folder and go to New > Android resource directory. The New
Resource Directory window appears.
2.)In the Resource type list, select font, and then click OK.
3.)Add your font files in the font folder.The folder structure below generates R.font.dancing_script, R.font.la_la, and R.font.ba_ba.
4.)Double-click a font file to preview the file's fonts in the editor.

Next we must create a font family

1.)Right-click the font folder and go to New > Font resource file. The New Resource File window appears.
2.)Enter the file name, and then click OK. The new font resource XML opens in the editor.
3.)Enclose each font file, style, and weight attribute in the font tag element. The following XML illustrates adding font-related attributes in the font resource XML:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="">
    android:font="@font/hey_regular" />
    android:font="@font/hey_bababa" />

Adding fonts to a TextView:


As from the documentation

Working With Fonts

all the steps are correct.

@Dmitry 2018-08-26 06:15:25

The best answer! The font filename must be in lowercase.

@goldenmaza 2019-01-27 00:31:42

You can also create a custom style that you apply to your application (under the AndroidManifest file) and it will be given to ALL views. Instead of for example just placing it on a single TextView, as this will not affect the Toolbar.

@norman784 2015-10-30 21:44:31

Also can be defined in the xml without creating custom classes


<style name="ionicons" parent="android:TextAppearance">
    <!-- Custom Attr-->
    <item name="fontPath">fonts/ionicons.ttf</item>


<LinearLayout xmlns:android=""
              android:orientation="vertical" >

A quick note, because I just always forgot where to put the fonts, its that the font must be inside assets and this folder resides in the same level that res and src, in my case its assets/fonts/ionicons.ttf

Updated Added root layout because this method needs xmlns:app="" to work

Update 2 Forgot about a library that I've installed before called Calligraphy

@Stef 2015-11-04 16:33:11

This does not work for me. When I try to build this I get the error message: Error:(49, 5) No resource found that matches the given name: attr 'fontPath'.

@norman784 2015-11-05 03:26:44

Try adding xmlns:app="" to your root layout, check the updated answer also

@Stef 2015-11-05 09:25:51

The error does not come from the layout XML file but from the styles XML file. It seems that it does not 'know' what a fontPath is.

@norman784 2015-11-05 18:57:44

Your right, forgot that I've a library called Calligrapy

@Chulo 2015-09-03 16:51:16

Using DataBinding :

public static void setFont(TextView textView, String fontName){
 textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));



font file must be in assets/fonts/

@Leonardo Cardoso 2013-04-22 05:40:01

This might be a little late, but you need to create a singleton class that returns the custom typeface to avoid memory leaks.

TypeFace class:

public class OpenSans {

private static OpenSans instance;
private static Typeface typeface;

public static OpenSans getInstance(Context context) {
    synchronized (OpenSans.class) {
        if (instance == null) {
            instance = new OpenSans();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
        return instance;

public Typeface getTypeFace() {
    return typeface;

Custom TextView:

public class NativelyCustomTextView extends TextView {

    public NativelyCustomTextView(Context context) {

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

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


By xml:

            android:textSize="30sp" /> 


TextView programmaticallyTextView = (TextView) 


@Magnus Johansson 2013-05-05 13:50:32

Seems to work at runtime, but is it supposed to work in the designer as well?

@Leonardo Cardoso 2013-05-05 22:32:49

Sure. You can use as xml. @Magnus

@Magnus Johansson 2013-05-06 11:25:39

I think you misunderstood, it doesn't seem to work in Design time (Designer preview). (xml != designer). It works fine specified in the Xml layout file compiled into runtime. Anyway, I'm using this extension, which works much better for my needs (it support multiple font styles, regular, bold etc. as well as different fonts names as well as other controls beyond TextView)

@Leonardo Cardoso 2013-05-06 19:14:19

Now I get it. No, it doesn't work at design time. I haven't work on it yet.

@Wolfgang Schreurs 2013-11-22 09:49:23

The above example seems to work fine for me (but indeed, won't show up in the designer).

@Steven Pena 2014-08-02 12:46:37

The getTypeFace creates a new typeface on every call...this defeats the purpose of the singleton. It should have a static field that is set the first time the call is made and returns the value of the field on subsequent calls.

@John Pang 2014-11-20 22:01:43

Great. Thanks. Just two questions, 1) why does the instance need to hold reference to the Context? 2) synchronized (Gothic.class)?

@Leonardo Cardoso 2014-11-20 22:24:06

@chiwai you're right! About the first question it doesn't need it. About the second it was a typo.

@John Pang 2014-11-20 22:46:34

One suggestion: Typeface typeface = getTypeface(); setTypeface(OpenSans.getInstance(context).g‌​etTypeFace(), null != typeface ? typeface.getStyle() : Typeface.NORMAL); to preserve the other style set in XML.

@Sagar Devanga 2014-12-30 13:04:39

@LeonardoCardoso you are using a Parameterized constructor in OpenSans when u dont even have one. Please clarify my doubt if i am wrong. Your Code : instance = new OpenSans(context);

@Sagar Devanga 2014-12-30 13:07:20

@LeonardoCardoso i got this error when i used your code. Am I missing something. I have used the class in XML android.view.InflateException: Binary XML file line #9: Error inflating class com.ascent.adwad.utils.CustomTextView

@Leonardo Cardoso 2015-01-03 07:30:20

@SagarDevanga You are right about the constructor... I forgot to remove the parameter. Just check if you are properly using the right references. If so, put your code here of your custom text view and xml you are inflating it on...

@Leonardo Cardoso 2015-01-03 07:33:35

@JohnPang a good suggestion, but it's not necessary because I think we won't create a custom font class to use normal fonts.

@Sagar Devanga 2015-01-05 05:41:55

@LeonardoCardoso problem solved. Thanx for the help. I was using android studio and was supposed to create the ASSETS folder under JAVA Main as contrast to RES in eclipse.

@John Pang 2015-01-14 18:11:21

@LeonardoCardoso Typeface.NORMAL is not "normal fonts" but "normal style". Other options are BOLD, BOLD_ITALIC, ITALIC.‌​ml If not call setTypeface, then any typeface settings (bold/italic) from XML will be lost.

@browep 2012-02-26 20:43:12

Here's a tutorial that shows you how to setup a custom font like @peter described:

it also has consideration for potential memory leaks ala . Also in the tutorial is an example for setting a custom font on a button.

@Sven Nähler 2014-11-30 10:41:40

Fontinator is an Android-Library make it easy, to use custom Fonts.

@thoutbeckers 2014-05-01 16:08:40

Old question, but I sure wish I read this answer here before I started my own search for a good solution. Calligraphy extends the android:fontFamily attribute to add support for custom fonts in your asset folder, like so:


The only thing you have to do to activate it is attaching it to the Context of the Activity you're using:

protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(new CalligraphyContextWrapper(newBase));

You can also specify your own custom attribute to replace android:fontFamily

It also works in themes, including the AppTheme.

@San 2013-12-13 09:18:00

I might have a simple answer for the question without extending the TextView and implementing a long code.

Code :

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

Place the custom font file in assets folder as usual and try this. It works for me. I just dont understand why peter has given such a huge code for this simple thing or he has given his answer in old version.

@peter 2011-08-25 22:14:20

You can extend TextView to set custom fonts as I learned here.

package com.example;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

    public TextViewPlus(Context context) {

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface tf = null;
        try {
        tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;

        return true;


attrs.xml: (in res/values)

<?xml version="1.0" encoding="utf-8"?>
    <declare-styleable name="TextViewPlus">
        <attr name="customFont" format="string"/>


<?xml version="1.0" encoding="utf-8"?>
    android:orientation="vertical" android:layout_width="fill_parent"


You would put "saxmono.ttf" in the assets folder.

UPDATE 8/1/13

There are serious memory concerns with this method. See chedabob's comment below.

@Majjoodi 2011-11-17 15:11:33

That looks nice, however, I'm getting an error when I try to use the "TextViewPlus" in the main.xml. I get the following: - error: Error parsing XML: unbound prefix - The prefix "foo" for attribute "foo:customFont" associated with an element type "supportLibs.TextViewPlus" is not bound.

@chedabob 2012-01-24 14:20:29

One thing to note is that this will generate dozens and dozens of TypeFace objects and eat up memory. There is a bug in pre-4.0 Android that doesn't free up TypeFaces properly. The easiest thing to do is create a TypeFace cache with a HashMap. This brought memory usage in my app down from 120+ mb to 18mb.

@Theo 2012-03-24 02:56:16

@Majjoodi: That typically happens if you forget to add the 2nd namespace to your layout: xmlns:foo="

@Michał K 2012-08-12 18:43:46

VERY IMPORTANT - I would just like to double stress chedabob's advice. Unless you follow it, you will have a memory leak in pre-ICS. There are few solutions, one of them is in the link provided by chedabob, another one is here: peter - please update your answer - it's great but not complete

@loeschg 2012-11-07 22:56:03

How do I set this custom attribute in styles.xml in addition to other textview attributes such as width and height?

@Tom Fobear 2013-04-06 22:08:43

Is there a way to use foo:customFont in styles.xml?

@Paul Lammertsma 2013-07-05 16:18:14

@TomFobear There certainly is! You could take a look at my presentation and sample code that I presented at mdevcon, Droidcon, Dev Days and MobDevCon. Not only does it answer your question precisely, but it is a general tutorial about how to create custom views.

@Tofeeq Ahmad 2013-07-12 05:45:24

Similar example here in details Applying custom Font using Layouts

@AlikElzin-kilaka 2013-08-01 13:14:28

What about the font of the actionbar? it's layout is hidden.

@AlikElzin-kilaka 2013-08-01 13:17:33

Also, isn't there a way to just define it as part of the theme, instead of manually defining it for every textview?

@Ragunath Jawahar 2013-12-05 10:43:57

@chedabob That's what TypefaceTextView does, you can check out my answer on that.

@Muhammed Refaat 2015-01-23 15:53:11

what about the memory problem now ?!! still on action ?!!

@febaisi 2016-06-29 20:48:50

I made a library for that. Just add the library compile and add this custom component. Everything by XML.

@M D P 2016-10-16 06:53:29

to avoid the memory problem, just define your typeface in a static global variable in your Application class then use that single instance everywhere.

@AA_PV 2017-01-12 04:40:29

@chedabob so maintaining such map isn't required for 4.0+, is that correct to say?

@Ragunath Jawahar 2013-05-09 11:58:20

I'm 3 years late for the party :( However this could be useful for someone who might stumble upon this post.

I've written a library that caches Typefaces and also allow you to specify custom typefaces right from XML. You can find the library here.

Here is how your XML layout would look like, when you use it.

    geekui:customTypeface="fonts/custom_font.ttf" />

@aimango 2014-06-14 23:21:57

Hey @Ragunath-jawahar, how would I import the library for a gradle project? I tried compile 'com.mobsandgeeks:android-typeface-textview:1.0' but that didn't work.

@Ragunath Jawahar 2014-06-17 15:21:55

You'll need an AAR to be able to use it that way. It's not there yet. You can copy the sources and build a Android Studio Library project for now.

@sefirosu 2014-07-14 12:37:23

where dose your geekui tag come from?

@Ragunath Jawahar 2014-07-15 10:20:39

From the namespace specified in the parent tag - xmlns:geekui=""

@Muhammed Refaat 2015-01-23 15:44:34

is your library solves the problem of @peter answer ?!! the memory problem

@Ragunath Jawahar 2015-01-23 23:50:30

@MuhammedRefaat, yes it does :)

@Jelle 2012-09-05 13:24:05

Peter's answer is the best, but it can be improved by using the styles.xml from Android to customize your fonts for all textviews in your app.

My code is here

@Tore Rudberg 2012-05-02 13:30:18

If you only have one typeface you would like to add, and want less code to write, you can create a dedicated TextView for your specific font. See code below.

package com.yourpackage;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;

    public FontTextView(Context context) {
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");

In main.xml, you can now add your textView like this:

    android:text="" />

@ericosg 2013-12-07 10:07:51

do this on init() and save yourself 3x the same call.

@Sagar Devanga 2014-12-30 12:53:26

@ericosg i get this error when i use yourthis solution android.view.InflateException: Binary XML file line #9: Error inflating class com.ascent.adwad.utils.CustomTextView

@ericosg 2014-12-31 09:09:07

@SagarDevanga, hard to help without more information. Perhaps take it as far as you can and make a new question.

@Carl Whalley 2011-03-16 18:36:49

You can't extend TextView to create a widget or use one in a widgets layout:

@Carl Whalley 2012-08-23 09:01:31

Aha - the famous double use of the word "widget" strikes again!

@Nathan Schwermann 2011-02-24 19:38:25

Extend TextView and give it a custom attribute or just use the android:tag attribute to pass in a String of what font you want to use. You will need to pick a convention and stick to it such as I will put all of my fonts in the res/assets/fonts/ folder so your TextView class knows where to find them. Then in your constructor you just set the font manually after the super call.

@Tareq Sha 2010-03-06 00:04:48

The only way to use custom fonts is through the source code.

Just remember that Android runs on devices with very limited resources and fonts might require a good amount of RAM. The built-in Droid fonts are specially made and, if you note, have many characters and decorations missing.

@Sandy 2012-08-10 03:33:10

"Just remember that Android runs on devices with very limited resources" --> this is becoming less and less the case. Quad core phone? Really??

@SK9 2012-12-18 12:45:13

I'd do more to show consideration of the context of tareqHs's answer, which predates your comment by a good 2 and a half years.

@cosmix 2013-10-03 14:50:19

The first part of your response may have been true when you wrote your answer in 2010. The latter is superfluoys and beside the point: Droid was bad, ditched by Google in 2012 in favour of Roboto. The lack of choice in typography in Android is a flaw, not a feature; iOS has had multiple fonts available to developers since 2008 under primitive devices by today's standards.

@Martin Konecny 2014-08-19 21:13:12

This answer is no longer valid.

Related Questions

Sponsored Content

50 Answered Questions

[SOLVED] Is there a unique Android device ID?

19 Answered Questions

[SOLVED] Can the Android Layout folder contain subfolders?

18 Answered Questions

[SOLVED] Fling gesture detection on grid layout

34 Answered Questions

[SOLVED] How to avoid reverse engineering of an APK file?

104 Answered Questions

[SOLVED] Close/hide android soft keyboard

52 Answered Questions

32 Answered Questions

[SOLVED] How to save an activity state using save instance state?

23 Answered Questions

[SOLVED] Is there a way to run Python on Android?

11 Answered Questions

[SOLVED] Proper use cases for Android UserManager.isUserAGoat()?

Sponsored Content