EDIT : Cela fait donc un moment, et j'aimerais ajouter ce que je pense être la meilleure façon de le faire, et par XML pas moins!
Donc, tout d'abord, vous allez vouloir créer une nouvelle classe qui remplace la vue que vous souhaitez personnaliser. (par exemple, vous voulez un bouton avec une police de caractères personnalisée? Étendre Button
). Faisons un exemple:
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);
}
}
Maintenant, si vous n'en avez pas, ajoutez un document XML sous res/values/attrs.xml
et ajoutez:
<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>
D'accord, donc avec cela à l'écart, revenons à la parseAttributes()
méthode précédente:
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();
}
Maintenant, vous êtes prêt. Vous pouvez ajouter plus d'attributs pour à peu près tout (vous pouvez en ajouter un autre pour typefaceStyle - gras, italique, etc.) mais voyons maintenant comment l'utiliser:
<?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
ligne peut vraiment être n'importe quoi, mais la convention est celle illustrée ci-dessus. Ce qui compte, c'est qu'il soit unique, et c'est pourquoi le nom du package est utilisé. Maintenant, vous utilisez simplement le custom:
préfixe pour vos attributs et le android:
préfixe pour les attributs Android.
Une dernière chose: si vous voulez utiliser ceci dans un style ( res/values/styles.xml
), vous ne devez pas ajouter la xmlns:custom
ligne. Faites simplement référence au nom de l'attribut sans préfixe:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
(PREVIOUS ANSWER)
Utilisation d'une police personnalisée sous Android
Cela devrait aider. Fondamentalement, il n'y a aucun moyen de le faire en XML, et pour autant que je sache, pas de moyen plus simple de le faire dans le code. Vous pouvez toujours avoir une méthode setLayoutFont () qui crée la police une fois, puis exécute setTypeface () pour chacune. Il vous suffit de le mettre à jour chaque fois que vous ajoutez un nouvel élément à une mise en page. Quelque chose comme ci-dessous:
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 : Donc je me suis mis à implémenter moi-même quelque chose comme ça, et comment j'ai fini par le faire était de créer une fonction comme celle-ci:
public static void setLayoutFont(Typeface tf, TextView...params) {
for (TextView tv : params) {
tv.setTypeface(tf);
}
}
Ensuite, utilisez simplement cette méthode de onCreate () et transmettez tous les TextViews que vous souhaitez mettre à jour:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);
MODIFIER 9/5/12:
Donc, comme cela continue de recevoir des vues et des votes, j'aimerais ajouter une méthode bien meilleure et plus complète:
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 vous lui passez la racine de votre mise en page, il recherchera récursivement TextView
ou Button
vues (ou toute autre que vous ajoutez à cette instruction if) dans cette mise en page, et définira la police sans que vous ayez à les spécifier par ID. Cela suppose bien sûr que vous souhaitez définir la police pour chaque vue.