EDITAR : Ha pasado un tiempo y me gustaría agregar lo que creo que es la mejor manera de hacer esto, ¡y a través de XML nada menos!
Entonces, primero, querrá crear una nueva clase que anule cualquier Vista que desee personalizar. (por ejemplo, ¿quieres un botón con un tipo de letra personalizado? Ampliar Button
). Hagamos un ejemplo:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I'll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
Ahora, si no tiene uno, agregue un documento XML debajo res/values/attrs.xml
y agregue:
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
Bien, con eso fuera del camino, volvamos al parseAttributes()
método de antes:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
Ahora estás listo. Puede agregar más atributos para casi cualquier cosa (podría agregar otro para typefaceStyle: negrita, cursiva, etc.) pero ahora veamos cómo usarlo:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
La xmlns:custom
línea realmente puede ser cualquier cosa, pero la convención es lo que se muestra arriba. Lo que importa es que es único y por eso se usa el nombre del paquete. Ahora solo usa el custom:
prefijo para tus atributos y el android:
prefijo para los atributos de Android.
Una última cosa: si quiere utilizar esto en un estilo ( res/values/styles.xml
), debe no agregar la xmlns:custom
línea. Simplemente haga referencia al nombre del atributo sin prefijo:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Usar un tipo de letra personalizado en Android
Esto debería ayudar. Básicamente, no hay forma de hacer esto en XML, y hasta donde yo sé, no hay una forma más fácil de hacerlo en código. Siempre puede tener un método setLayoutFont () que cree el tipo de letra una vez y luego ejecute setTypeface () para cada uno. Solo tendría que actualizarlo cada vez que agregue un nuevo elemento a un diseño. Algo como a continuación:
public void setLayoutFont() {
Typeface tf = Typeface.createFromAsset(
getBaseContext().getAssets(), "fonts/BPreplay.otf");
TextView tv1 = (TextView)findViewById(R.id.tv1);
tv1.setTypeface(tf);
TextView tv2 = (TextView)findViewById(R.id.tv2);
tv2.setTypeface(tf);
TextView tv3 = (TextView)findViewById(R.id.tv3);
tv3.setTypeface(tf);
}
EDITAR : Así que empecé a implementar algo como esto yo mismo, y cómo terminé haciéndolo fue haciendo una función como esta:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Luego, simplemente use este método de onCreate () y pase todos los TextViews que desea actualizar:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
EDITAR 5/09/12:
Entonces, dado que esto todavía está obteniendo vistas y votos, me gustaría agregar un método mucho mejor y más completo:
Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);
/*
* Sets the font on all TextViews in the ViewGroup. Searches
* recursively for all inner ViewGroups as well. Just add a
* check for any other views you want to set as well (EditText,
* etc.)
*/
public void setFont(ViewGroup group, Typeface font) {
int count = group.getChildCount();
View v;
for(int i = 0; i < count; i++) {
v = group.getChildAt(i);
if(v instanceof TextView || v instanceof Button /*etc.*/)
((TextView)v).setTypeface(font);
else if(v instanceof ViewGroup)
setFont((ViewGroup)v, font);
}
}
Si le pasa la raíz de su diseño, buscará de forma recursiva TextView
o Button
vistas (o cualquier otra que agregue a esa declaración if) dentro de ese diseño, y establecerá la fuente sin que tenga que especificarlas por ID. Por supuesto, esto supone que desea configurar la fuente para cada vista.