273 votes

Est-il possible de définir la police pour toute l'application ?

Je dois utiliser une certaine police pour l'ensemble de mon application. J'ai un fichier .ttf pour cette police. Est-il possible de la définir comme police par défaut, au démarrage de l'application, puis de l'utiliser ailleurs dans l'application ? Une fois définie, comment puis-je l'utiliser dans mes XML de mise en page ?

Un exemple de code, un tutoriel qui peut m'aider ici est apprécié.

Merci.

455voto

weston Points 11882

Oui avec réflexion. Cela fonctionne ( sur la base de cette réponse ) :

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {

    public static void setDefaultFont(Context context,
            String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(),
                fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    }

    protected static void replaceFont(String staticTypefaceFieldName,
            final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

Vous devez ensuite surcharger les quelques polices par défaut, par exemple :

FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset3.ttf");

Bien entendu, si vous utilisez le même fichier de police, vous pouvez l'améliorer pour ne le charger qu'une seule fois.

Cependant, j'ai tendance à ne remplacer qu'un seul de ces éléments, par exemple "MONOSPACE" puis définissez un style pour forcer l'utilisation de cette police de caractères dans toute l'application :

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Light">
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:typeface">monospace</item>
    </style>
</resources>

47voto

Tom Points 2816

Bien que cela ne fonctionne pas pour une application entière, cela fonctionnerait pour une activité et pourrait être réutilisé pour toute autre activité. J'ai mis à jour mon code grâce à @FR073N pour supporter d'autres vues. Je ne suis pas sûr des problèmes avec Buttons , RadioGroups etc., car ces classes étendent toutes TextView donc ils devraient fonctionner parfaitement. J'ai ajouté une condition booléenne pour l'utilisation de la réflexion parce que cela semble très bricolé et pourrait notamment compromettre les performances.

Note : comme indiqué, cela ne fonctionnera pas pour le contenu dynamique ! Pour cela, il est possible d'appeler cette méthode avec, par exemple, un fichier de type onCreateView ou getView mais elle nécessite un effort supplémentaire.

/**
 * Recursively sets a {@link Typeface} to all
 * {@link TextView}s in a {@link ViewGroup}.
 */
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{
    if (mContainer == null || mFont == null) return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children.
    for (int i = 0; i < mCount; ++i)
    {
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView)
        {
            // Set the font if it is a TextView.
            ((TextView) mChild).setTypeface(mFont);
        }
        else if (mChild instanceof ViewGroup)
        {
            // Recursively attempt another ViewGroup.
            setAppFont((ViewGroup) mChild, mFont);
        }
        else if (reflect)
        {
            try {
                Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
                mSetTypeface.invoke(mChild, mFont); 
            } catch (Exception e) { /* Do something... */ }
        }
    }
}

Ensuite, pour l'utiliser, vous devez faire quelque chose comme ceci :

final Typeface mFont = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"); 
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, mFont);

J'espère que cela vous aidera.

15voto

palani Points 36

C'est très simple... Téléchargez et mettez votre police personnalisée dans les actifs, puis écrivez une classe séparée pour la vue du texte comme suit : ici, j'ai utilisé la police Futura.

public class CusFntTextView extends TextView {

public CusFntTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

public CusFntTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CusFntTextView(Context context) {
    super(context);
    init();
}

private void init() {
    if (!isInEditMode()) {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
        setTypeface(tf);
    }
}

}

et faites ce qui suit dans xml :

 <com.packagename.CusFntTextView
        android:id="@+id/tvtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"         
        android:text="Hi Android"           
        android:textAppearance="?android:attr/textAppearanceLarge"
      />

9voto

Andrey Mischenko Points 1131

Je suggérerais également d'étendre TextView et d'autres contrôles, mais je pense qu'il serait préférable de mettre en place une police dans les constructions.

public FontTextView(Context context) {
    super(context);
    init();
}

public FontTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public FontTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

protected void init() {
    setTypeface(Typeface.createFromAsset(getContext().getAssets(), AppConst.FONT));
}

3voto

Sam Dozor Points 5709

Je vous suggère d'étendre TextView et de toujours utiliser votre TextView personnalisé dans vos mises en page XML ou partout où vous avez besoin d'un TextView. Dans votre TextView personnalisé, remplacez setTypeface

@Override
public void setTypeface(Typeface tf, int style) {
    //to handle bold, you could also handle italic or other styles here as well
    if (style == 1){
        tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans700.otf");
    }else{
        tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans500.otf");
    }
    super.setTypeface(tf, 0);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X