Using custom font in android TextView using xml Using custom font in android TextView using xml android android

Using custom font in android TextView using xml


Short answer: No. Android doesn't have built-in support for applying custom fonts to text widgets through XML.

However, there's a workaround that's not terribly difficult to implement.

First

You'll need to define your own stylable. In your /res/values folder, open/create the attrs.xml file and add a declare-styleable object like so:

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

Second

Assuming you want to use this widget often, you should set up a simple cache for the loaded Typeface objects, since loading them from memory on the fly can take time. Something like:

public class FontManager {    private static FontManager instance;    private AssetManager mgr;    private Map<String, Typeface> fonts;    private FontManager(AssetManager _mgr) {        mgr = _mgr;        fonts = new HashMap<String, Typeface>();    }    public static void init(AssetManager mgr) {        instance = new FontManager(mgr);    }    public static FontManager getInstance() {        if (instance == null) {            // App.getContext() is just one way to get a Context here            // getContext() is just a method in an Application subclass            // that returns the application context            AssetManager assetManager = App.getContext().getAssets();            init(assetManager);        }        return instance;    }    public Typeface getFont(String asset) {        if (fonts.containsKey(asset))            return fonts.get(asset);        Typeface font = null;        try {            font = Typeface.createFromAsset(mgr, asset);            fonts.put(asset, font);        } catch (Exception e) {        }        if (font == null) {            try {                String fixedAsset = fixAssetFilename(asset);                font = Typeface.createFromAsset(mgr, fixedAsset);                fonts.put(asset, font);                fonts.put(fixedAsset, font);            } catch (Exception e) {            }        }        return font;    }    private String fixAssetFilename(String asset) {        // Empty font filename?        // Just return it. We can't help.        if (TextUtils.isEmpty(asset))            return asset;        // Make sure that the font ends in '.ttf' or '.ttc'        if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc")))            asset = String.format("%s.ttf", asset);        return asset;    }}

This one will allow you to use .ttc file extensions, but it's untested.

Third

Create a new class that subclasses TextView. This particular example takes into account the defined XML typeface (bold, italic, etc.) and apply it to the font (assuming you're using a .ttc file).

/** * TextView subclass which allows the user to define a truetype font file to use as the view's typeface. */public class FontText extends TextView {    public FontText(Context context) {        this(context, null);    }    public FontText(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public FontText(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        if (isInEditMode())            return;        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText);        if (ta != null) {            String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset);            if (!TextUtils.isEmpty(fontAsset)) {                Typeface tf = FontManager.getInstance().getFont(fontAsset);                int style = Typeface.NORMAL;                float size = getTextSize();                if (getTypeface() != null)                    style = getTypeface().getStyle();                if (tf != null)                    setTypeface(tf, style);                else                    Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset));            }        }    }}

Finally

Replace the instances of TextView in your XML with the fully qualified class name. Declare your custom namespace just like you would the Android namespace. Note that the "typefaceAsset" should point to a .ttf or .ttc file contained in your /assets directory.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:custom="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.example.FontText        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="This is a custom font text"        custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/></RelativeLayout>


Here is example code that does this. I have the font defined in a static final variable and the font file is in the assets directory.

public class TextViewWithFont extends TextView {    public TextViewWithFont(Context context, AttributeSet attrs) {        super(context, attrs);        this.setTypeface(MainActivity.typeface);    }    public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        this.setTypeface(MainActivity.typeface);    }    public TextViewWithFont(Context context) {        super(context);        this.setTypeface(MainActivity.typeface);    }}


Create your customed TextView belong to the font you want to use. In this class, I use a static mTypeface field to cache the Typeface (for better performance)

public class HeliVnTextView extends TextView {/* * Caches typefaces based on their file path and name, so that they don't have to be created every time when they are referenced. */private static Typeface mTypeface;public HeliVnTextView(final Context context) {    this(context, null);}public HeliVnTextView(final Context context, final AttributeSet attrs) {    this(context, attrs, 0);}public HeliVnTextView(final Context context, final AttributeSet attrs, final int defStyle) {    super(context, attrs, defStyle);     if (mTypeface == null) {         mTypeface = Typeface.createFromAsset(context.getAssets(), "HelveticaiDesignVnLt.ttf");     }     setTypeface(mTypeface);}}

In xml file:

<java.example.HeliVnTextView        android:id="@+id/textView1"        android:layout_width="0dp"        ... />

In java class:

HeliVnTextView title = new HeliVnTextView(getActivity());title.setText(issue.getName());