EDIT : Já faz um tempo e gostaria de acrescentar o que acho que é a melhor maneira de fazer isso, nada menos que por meio de XML!
Então, primeiro, você vai querer fazer uma nova classe que substitui qualquer View que você deseja personalizar. (por exemplo, deseja um botão com uma fonte personalizada? Estender Button
). Vamos dar um exemplo:
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);
}
}
Agora, se você não tiver um, adicione um documento XML em res/values/attrs.xml
e adicione:
<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>
Ok, então com isso fora do caminho, vamos voltar ao parseAttributes()
método anterior:
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();
}
Agora você está pronto. Você pode adicionar mais atributos para qualquer coisa (você pode adicionar outro para typefaceStyle - negrito, itálico, etc.), mas agora vamos ver como usá-lo:
<?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>
A xmlns:custom
linha pode realmente ser qualquer coisa, mas a convenção é o que é mostrado acima. O que importa é que ele seja único e é por isso que o nome do pacote é usado. Agora você apenas usa o custom:
prefixo para seus atributos e o android:
prefixo para atributos do Android.
Uma última coisa: se você quiser usar isso em um estilo ( res/values/styles.xml
), você deve não adicionar a xmlns:custom
linha. Basta fazer referência ao nome do atributo sem prefixo:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Usando uma fonte personalizada no Android
Isso deve ajudar. Basicamente, não há como fazer isso em XML e, até onde sei, não há maneira mais fácil de fazer isso em código. Você sempre pode ter um método setLayoutFont () que cria o tipo de letra uma vez e, em seguida, executa setTypeface () para cada um. Você apenas teria que atualizá-lo cada vez que adicionar um novo item a um layout. Algo como abaixo:
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);
}
EDIT : Então, acabei de implementar algo como isso sozinho, e como acabei fazendo isso foi criar uma função como esta:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Depois, basta usar este método de onCreate () e passar todos os TextViews que deseja atualizar:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
EDITAR 05/09/12:
Então, como isso ainda está recebendo visualizações e votos, gostaria de adicionar um método muito melhor e mais 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);
}
}
Se você passar a raiz do seu layout, ele verificará recursivamente por TextView
ou Button
visualizações (ou quaisquer outras que você adicionar a essa instrução if) dentro desse layout e definirá a fonte sem que você precise especificá-los por ID. Isso, claro, pressupõe que você deseja definir a fonte para cada visualização.