174

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.

DrDefrost
  • 1,807
  • 3
  • 12
  • 5
  • 69
    DrDefrost - please accept some answers, you'll get more responses on this site. – Ken Sep 03 '11 at 01:52
  • 1
    Here's one more similar question : http://stackoverflow.com/questions/9030204/how-to-use-custom-font-in-android-xml – Vins May 16 '13 at 13:12
  • Updated 05/2017: "The Support Library 26.0 Beta provides support to the Fonts in XML feature on devices running Android API version 14 and higher." See: https://developer.android.com/preview/features/fonts-in-xml.html#using-support-lib – albert c braun May 23 '17 at 14:12

18 Answers18

220

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

TextViewPlus.java:

package com.example;

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;

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

    public TextViewPlus(Context context) {
        super(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);
        a.recycle();
    }

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

        setTypeface(tf);  
        return true;
    }

}

attrs.xml: (in res/values)

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

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res/com.example"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.example.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="saxmono.ttf">
    </com.example.TextViewPlus>
</LinearLayout>

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.

Community
  • 1
  • 1
peter
  • 6,067
  • 2
  • 33
  • 44
  • 5
    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. – Majjoodi Nov 17 '11 at 15:11
  • 79
    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. http://code.google.com/p/android/issues/detail?id=9904 – chedabob Jan 24 '12 at 14:20
  • 7
    @Majjoodi: That typically happens if you forget to add the 2nd namespace to your layout: `xmlns:foo="http://schemas.android.com/apk/res/com.example` – Theo Mar 24 '12 at 02:56
  • 11
    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: http://stackoverflow.com/questions/8057010/listview-memory-leak. peter - please update your answer - it's great but not complete – Michał Klimczak Aug 12 '12 at 18:43
  • 1
    How do I set this custom attribute in styles.xml in addition to other textview attributes such as width and height? – loeschg Nov 07 '12 at 22:56
  • 1
    Is there a way to use `foo:customFont` in `styles.xml`? – Tom Fobear Apr 06 '13 at 22:08
  • 1
    @TomFobear There certainly is! You could take a look at my [presentation and sample code](https://github.com/pflammertsma/mobdevcon) 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. – Paul Lammertsma Jul 05 '13 at 16:18
  • Similar example here in details [Applying custom Font using Layouts](http://androidtrainningcenter.blogspot.in/2013/07/applying-custom-font-in-entire-android.html) – Tofeeq Ahmad Jul 12 '13 at 05:45
  • What about the font of the actionbar? it's layout is hidden. – AlikElzin-kilaka Aug 01 '13 at 13:14
  • Also, isn't there a way to just define it as part of the theme, instead of manually defining it for every textview? – AlikElzin-kilaka Aug 01 '13 at 13:17
  • @chedabob That's what TypefaceTextView does, you can check out my answer on that. – Ragunath Jawahar Dec 05 '13 at 10:43
  • what about the memory problem now ?!! still on action ?!! – Muhammed Refaat Jan 23 '15 at 15:53
  • I made a library for that. https://github.com/febaisi/CustomTextView Just add the library compile and add this custom component. Everything by XML. – febaisi Jun 29 '16 at 20:48
  • to avoid the memory problem, just define your typeface in a static global variable in your Application class then use that single instance everywhere. – M D P Oct 16 '16 at 06:53
  • @chedabob so maintaining such map isn't required for 4.0+, is that correct to say? – AA_PV Jan 12 '17 at 04:40
35

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.

<com.mobsandgeeks.ui.TypefaceTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    geekui:customTypeface="fonts/custom_font.ttf" />
Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
18

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) {
        super(context);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

}

By xml:

<com.yourpackage.views.NativelyCustomTextView
            android:id="@+id/natively_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="20dp"
            android:text="@string/natively"
            android:textSize="30sp" /> 

Programmatically:

TextView programmaticallyTextView = (TextView) 
       findViewById(R.id.programmatically_text_view);

programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
                .getTypeFace());
Leonardo Cardoso
  • 1,164
  • 2
  • 12
  • 22
  • Seems to work at runtime, but is it supposed to work in the designer as well? – Magnus Johansson May 05 '13 at 13:50
  • Sure. You can use as xml. @Magnus – Leonardo Cardoso May 05 '13 at 22:32
  • 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 https://github.com/danh32/Fontify, 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) – Magnus Johansson May 06 '13 at 11:25
  • Now I get it. No, it doesn't work at design time. I haven't work on it yet. – Leonardo Cardoso May 06 '13 at 19:14
  • The above example seems to work fine for me (but indeed, won't show up in the designer). – Wolfgang Schreurs Nov 22 '13 at 09:49
  • 2
    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. – Steven Pena Aug 02 '14 at 12:46
  • Great. Thanks. Just two questions, 1) why does the instance need to hold reference to the Context? 2) synchronized (Gothic.class)? – John Pang Nov 20 '14 at 22:01
  • 1
    @chiwai you're right! About the first question it doesn't need it. About the second it was a typo. – Leonardo Cardoso Nov 20 '14 at 22:24
  • One suggestion: Typeface typeface = getTypeface(); setTypeface(OpenSans.getInstance(context).getTypeFace(), null != typeface ? typeface.getStyle() : Typeface.NORMAL); to preserve the other style set in XML. – John Pang Nov 20 '14 at 22:46
  • @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 Dec 30 '14 at 13:04
  • @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 – Sagar Devanga Dec 30 '14 at 13:07
  • @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 Jan 03 '15 at 07:30
  • @JohnPang a good suggestion, but it's not necessary because I think we won't create a custom font class to use normal fonts. – Leonardo Cardoso Jan 03 '15 at 07:33
  • @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. – Sagar Devanga Jan 05 '15 at 05:41
  • @LeonardoCardoso Typeface.NORMAL is not "normal fonts" but "normal style". Other options are BOLD, BOLD_ITALIC, ITALIC. http://developer.android.com/reference/android/graphics/Typeface.html If not call setTypeface, then any typeface settings (bold/italic) from XML will be lost. – John Pang Jan 14 '15 at 18:11
13

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:

<TextView 
  android:text="@string/hello_world"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:fontFamily="fonts/Roboto-Bold.ttf"/>

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

@Override
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.

thoutbeckers
  • 2,599
  • 22
  • 24
8

Using DataBinding :

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
 textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

In XML:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

font file must be in assets/fonts/

TooCool
  • 10,598
  • 15
  • 60
  • 85
7

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.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;


    public FontTextView(Context context) {
        super(context);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    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");
        this.setTypeface(FONT_NAME);
    }
}

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

<com.yourpackage.FontTextView
    android:id="@+id/tvTimer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />
Tore Rudberg
  • 1,594
  • 15
  • 16
  • do this on init() and save yourself 3x the same call. – ericosg Dec 07 '13 at 10:07
  • @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 – Sagar Devanga Dec 30 '14 at 12:53
  • @SagarDevanga, hard to help without more information. Perhaps take it as far as you can and make a new question. – ericosg Dec 31 '14 at 09:09
7

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="http://schemas.android.com/apk/res/android">
    <font
    android:fontStyle="normal"
    android:fontWeight="400"
    android:font="@font/hey_regular" />
    <font
    android:fontStyle="italic"
    android:fontWeight="400"
    android:font="@font/hey_bababa" />
</font-family>

Adding fonts to a TextView:

   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    **android:fontFamily="@font/ba_ba"**/>

As from the documentation

Working With Fonts

all the steps are correct.

jeevan s
  • 631
  • 9
  • 17
  • 1
    The best answer! The font filename must be in lowercase. – Dmitry Aug 26 '18 at 06:15
  • 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. – goldenmaza Jan 27 '19 at 00:31
5

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.

Nathan Schwermann
  • 31,285
  • 16
  • 80
  • 91
4

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.

Tareq Sha
  • 515
  • 4
  • 14
  • "Just remember that Android runs on devices with very limited resources" --> this is becoming less and less the case. Quad core phone? Really?? – Sandy Aug 10 '12 at 03:33
  • 9
    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. – Ken Dec 18 '12 at 12:45
  • 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. – cosmix Oct 03 '13 at 14:50
  • This answer is no longer valid. – Martin Konecny Aug 19 '14 at 21:13
2

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

Code :

 TextView tv = (TextView) findViewById(R.id.textview1);
    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.

San
  • 2,078
  • 1
  • 24
  • 42
2

Also can be defined in the xml without creating custom classes

style.xml

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

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/ionicons"
        android:text=""/>
</LinearLayout>

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="http://schemas.android.com/apk/res-auto" to work

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

norman784
  • 2,201
  • 3
  • 24
  • 31
  • 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'. – Stef Nov 04 '15 at 16:33
  • Try adding `xmlns:app="http://schemas.android.com/apk/res-auto"` to your root layout, check the updated answer also – norman784 Nov 05 '15 at 03:26
  • 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. – Stef Nov 05 '15 at 09:25
  • Your right, forgot that I've a library called Calligrapy – norman784 Nov 05 '15 at 18:57
1

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

Community
  • 1
  • 1
Jelle
  • 919
  • 9
  • 16
1

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

AppController.java

public class AppController extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

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

    }
}

FontsOverride.java

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.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

Way 2: use setTypeface

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

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

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

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

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

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

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

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) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
0

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) {
        super(context);
        init(null, context);
    }

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "http://schemas.android.com/apk/res-auto", "Lato-Regular.ttf",
                        -1);
            }
            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("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1).

Or

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) {
            tv.setTypeface(typeface);
        }
    }
}
duggu
  • 37,851
  • 12
  • 116
  • 113
0

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>

Vic
  • 1,778
  • 3
  • 19
  • 37
0

Here's a tutorial that shows you how to setup a custom font like @peter described: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

it also has consideration for potential memory leaks ala http://code.google.com/p/android/issues/detail?id=9904 . Also in the tutorial is an example for setting a custom font on a button.

browep
  • 5,057
  • 5
  • 29
  • 37
-1

Fontinator is an Android-Library make it easy, to use custom Fonts. https://github.com/svendvd/Fontinator

Sven Nähler
  • 277
  • 2
  • 4
-5

You can't extend TextView to create a widget or use one in a widgets layout: http://developer.android.com/guide/topics/appwidgets/index.html

Carl Whalley
  • 3,011
  • 8
  • 33
  • 48