Custom fonts and XML layouts (Android) Custom fonts and XML layouts (Android) android android

Custom fonts and XML layouts (Android)


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.


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" />


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