Usar fuentes personalizadas en un componente TextView desde XML 
Inauguro la sección de desarrollo Android de mi blog con un problema que se puede dar a la hora de desarrollar una app en Android y que, casi siempre, se soluciona de forma puramente programática: El uso de fuentes propias de tipo TrueType u OpenType en los textos de nuestra app.

Lo habitual es poner el componente TextView en el layout y luego, desde código, hacer lo siguiente:
TextView text = (TextView) findViewById(R.id.miTextView);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/fuente.otf");
text.setTypeface(tf);

Esta aproximación puramente programática a la solución del problema tiene un inconveniente clarísimo: Hay que hacer esto para cada componente TextView al que le queramos cambiar la fuente.

La solución que he encontrado es híbrida (mitad XML, mitad programática), pero requiere de mucho menos esfuerzo y es mucho más modular y elegante:

1. Lo primero que hay que hacer es colocar los ficheros TrueType y/o OpenType en la carpeta assets/fonts de nuestro proyecto.

2. Creamos una clase que herede de TextView, parecida a esta :-)
package org.atlantes.avelino.android;

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

public class MyTextView extends TextView {
protected static HashMap<String,Typeface> typefaceCache
= new HashMap<String,Typeface>();

public MyTextView(Context context) {
super(context);
}

public MyTextView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
this.init(attributeSet.getAttributeValue(
"http://avelino.atlantes.org/android",
"fontFile"));
}

public MyTextView(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
this.init(attributeSet.getAttributeValue(
"http://avelino.atlantes.org/android",
"fontFile"));
}

protected final void init(String fileName) {
if (fileName != null) {
Typeface tf = typefaceCache.get(fileName);
if (tf == null) {
tf = Typeface.createFromAsset(
this.getContext().getAssets(),
"fonts/" + fileName);
typefaceCache.put(fileName, tf);
}
this.setTypeface(tf);
}
}
}

3. En el fichero de layout podemos utilizar el nuevo componente MyTextView. Ojo con el nuevo namespace que debemos usar en el XML para el nuevo atributo fontFile:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:avelino="http://avelino.atlantes.org/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
...
<org.atlantes.avelino.android.MyTextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="abcd" android:textSize="50sp"
avelino:fontFile="fuente.ttf"/>
...
</LinearLayout>

Ya tenemos nuestro propio TextView que nos permite indicar la fuente que queremos usar en el propio XML :-)

Comentarios 
Lo sentimos. No se permiten nuevos comentarios después de 90 días.