web-dev-qa-db-fra.com

Comment définir la famille de polices par défaut pour toute l'application Android

J'utilise la police Roboto Light dans mon application. Pour définir la police, je dois ajouter le Android:fontFamily="sans-serif-light" à chaque vue. Est-il possible de déclarer la police Roboto en tant que famille de polices par défaut pour l'ensemble de l'application? J'ai essayé comme ça mais ça n'a pas semblé marcher.

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

<style name="AppTheme" parent="AppBaseTheme">
    <item name="Android:fontFamily">sans-serif-light</item>
</style>
214
tomrozb

La réponse est oui.

Lampe Global Roboto pour les classes TextView et Button:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="Android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="Android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="Android:Widget.TextView">
    <item name="Android:fontFamily">sans-serif-light</item>
</style>

<style name="RobotoButtonStyle" parent="Android:Widget.Holo.Button">
    <item name="Android:fontFamily">sans-serif-light</item>
</style>

Sélectionnez simplement le style de votre choix dans list themes.xml , puis créez votre style personnalisé en fonction du style original. A la fin, appliquez le style en tant que thème de l'application.

<application
    Android:theme="@style/AppTheme" >
</application>

Cela fonctionnera uniquement avec les polices intégrées telles que Roboto, mais telle était la question. Pour les polices personnalisées (chargées à partir d'actifs, par exemple), cette méthode ne fonctionnera pas.

EDIT 08/13/15

Si vous utilisez des thèmes AppCompat, n'oubliez pas de supprimer le préfixe Android:. Par exemple:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="Android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="buttonStyle">@style/RobotoButtonStyle</item>
</style>

Notez que buttonStyle ne contient pas le préfixe Android:, mais textViewStyle doit le contenir.

239
tomrozb

Avec la sortie d'Android Oreo, vous pouvez utiliser la bibliothèque de support pour atteindre cet objectif.

  1. Vérifiez votre application build.gradle si vous avez la bibliothèque de support > = 26.0.0
  2. Ajoutez le dossier "font" à votre dossier de ressources et ajoutez-y vos polices
  3. Référencez votre famille de polices par défaut dans le style principal de votre application:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
       <item name="Android:fontFamily">@font/your_font</item>
       <item name="fontFamily">@font/your_font</item> <!-- target Android sdk versions < 26 and > 14 if theme other than AppCompat -->
    </style>
    

Consultez https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html pour plus d'informations.

98
João Magalhães

LIRE LES MISES À JOUR CI-DESSOUS

J'avais le même problème avec l'incorporation d'une nouvelle police et je l'ai finalement fait fonctionner avec l'extension de TextView et la définition de la police de caractères à l'intérieur.

public class YourTextView extends TextView {

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

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

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

    private void init() {
        Typeface tf = Typeface.createFromAsset(context.getAssets(),
            "fonts/helveticaneue.ttf");
        setTypeface(tf);
    }
}

Vous devez modifier les éléments TextView plus tard de de à dans chaque élément. Et si vous utilisez UI-Creator dans Eclipse, il n’affiche parfois pas les droits TextViews. Était la seule chose qui fonctionne pour moi ...

METTRE &AGRAVE; JOUR

De nos jours, j'utilise la réflexion pour changer les polices de caractères dans toute l'application sans étendre TextViews. Découvrez ce SO post

UPDATE 2

À partir de l’API Niveau 26 et disponible dans la «bibliothèque de support», vous pouvez utiliser 

Android:fontFamily="@font/embeddedfont"

Informations complémentaires: Polices en XML

32
longilong

Ne parlez pas de performances. Pour les polices personnalisées, vous pouvez utiliser une méthode récursive pour parcourir toutes les vues et définir le type de caractère s’il s’agit d’un TextView:

public class Font {
    public static void setAllTextView(ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setAllTextView((ViewGroup) child);
            } else if (child instanceof TextView) {
                ((TextView) child).setTypeface(getFont());
            }
        }
    }

    public static Typeface getFont() {
        return Typeface.createFromAsset(YourApplicationContext.getInstance().getAssets(), "fonts/whateverfont.ttf");
    }
}

Dans toute votre activité, passez le groupe de vues actuel après setContentView et le tour est joué:

ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(Android.R.id.content);
Font.setAllTextView(group);

Pour fragment, vous pouvez faire quelque chose de similaire.

6
Allen Chan

Pour changer la police de votre application, procédez comme suit: 

  1. Dans le répertoire res, créez un nouveau répertoire et appelez-le font.
  2. Insérez votre police .ttf/.otf dans le dossier de polices, assurez-vous que le nom de la police est composé de lettres minuscules et de caractères de soulignement seulement.
  3. Dans res -> values -> styles.xml dans <resources> -> <style> ajoutez votre police <item name="Android:fontFamily">@font/font_name</item>.

 enter image description here

Maintenant, tout le texte de votre application doit être dans la source que vous ajoutez.

4
guy

Une autre façon de faire cela pour l’ensemble de l’application utilise une réflexion basée sur ceci answer

public class TypefaceUtil {
    /**
     * Using reflection to override default typefaces
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE
     * OVERRIDDEN
     *
     * @param typefaces map of fonts to replace
     */
    public static void overrideFonts(Map<String, Typeface> typefaces) {
        try {
            final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
            if (oldFonts != null) {
                oldFonts.putAll(typefaces);
            } else {
                oldFonts = typefaces;
            }
            field.set(null, oldFonts);
            field.setAccessible(false);
        } catch (Exception e) {
            Log.e("TypefaceUtil", "Can not set custom fonts");
        }
    }

    public static Typeface getTypeface(int fontType, Context context) {
        // here you can load the Typeface from asset or use default ones
        switch (fontType) {
            case BOLD:
                return Typeface.create(SANS_SERIF, Typeface.BOLD);
            case ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.ITALIC);
            case BOLD_ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.BOLD_ITALIC);
            case LIGHT:
                return Typeface.create(SANS_SERIF_LIGHT, Typeface.NORMAL);
            case CONDENSED:
                return Typeface.create(SANS_SERIF_CONDENSED, Typeface.NORMAL);
            case THIN:
                return Typeface.create(SANS_SERIF_MEDIUM, Typeface.NORMAL);
            case MEDIUM:
                return Typeface.create(SANS_SERIF_THIN, Typeface.NORMAL);
            case REGULAR:
            default:
                return Typeface.create(SANS_SERIF, Typeface.NORMAL);
        }
    }
}

ensuite, chaque fois que vous souhaitez remplacer les polices, vous pouvez simplement appeler la méthode et lui donner une carte des types de caractères comme suit:

Typeface regular = TypefaceUtil.getTypeface(REGULAR, context);
Typeface light = TypefaceUtil.getTypeface(REGULAR, context);
Typeface condensed = TypefaceUtil.getTypeface(CONDENSED, context);
Typeface thin = TypefaceUtil.getTypeface(THIN, context);
Typeface medium = TypefaceUtil.getTypeface(MEDIUM, context);
Map<String, Typeface> fonts = new HashMap<>();
fonts.put("sans-serif", regular);
fonts.put("sans-serif-light", light);
fonts.put("sans-serif-condensed", condensed);
fonts.put("sans-serif-thin", thin);
fonts.put("sans-serif-medium", medium);
TypefaceUtil.overrideFonts(fonts);

pour un exemple complet vérifier

Cela ne fonctionne que pour Android SDK 21 et supérieur pour les versions antérieures, consultez l'exemple complet.

4
Ismail Almetwally

Il suffit d'utiliser cette bibliothèque pour la compiler dans votre fichier de notes 

complie'me.anwarshahriar:calligrapher:1.0'

et l'utiliser dans la méthode onCreate dans l'activité principale 

Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "yourCustomFontHere.ttf", true);

C'est le moyen le plus élégant et rapide de le faire.

4
Mohamed Ayed

Ceci est un travail pour mon projet, source https://Gist.github.com/artem-zinnatullin/7749076

Créez un répertoire de polices dans Asset Folder, puis copiez votre police personnalisée dans le répertoire de polices, par exemple, j'utilise trebuchet.ttf;

Créez une classe TypefaceUtil.Java;

import Android.content.Context;
import Android.graphics.Typeface;
import Android.util.Log;

import Java.lang.reflect.Field;
public class TypefaceUtil {

    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {

        }
    }
}

Modifier le thème dans styles.xml ajouter ci-dessous

<item name="Android:typeface">serif</item>

Exemple dans Mes styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="Android:typeface">serif</item><!-- Add here -->
    </style>


    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="Android:windowActionBarOverlay">true</item>
        <item name="Android:windowFullscreen">true</item>
    </style>
</resources>

Enfin, dans Activity ou Fragment onCreate, appelez TypefaceUtil.Java.

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TypefaceUtil.overrideFont(getContext(), "SERIF", "fonts/trebuchet.ttf");
    }
0
Irvan Dwi Pangga

Essayez cette bibliothèque, elle est légère et facile à mettre en œuvre

https://github.com/sunnag7/FontStyler

<com.sunnag.fontstyler.FontStylerView
              Android:textStyle="bold"
              Android:text="@string/about_us"
              Android:layout_width="match_parent"
              Android:layout_height="match_parent"
              Android:paddingTop="8dp"
              app:fontName="Lato-Bold"
              Android:textSize="18sp"
              Android:id="@+id/textView64" />
0
Sanny Nagveker

Android ne fournit pas beaucoup de support pour l'application de polices dans l'ensemble de l'application (voir this issue ). Vous avez 4 options pour définir la police pour toute l'application:

  • Option 1: appliquer une réflexion pour changer la police du système 
  • Option 2: Créer et sous-classer les classes View personnalisées pour chaque vue nécessitant une police personnalisée 
  • Option 3: implémenter un explorateur de vue qui traverse la hiérarchie de la vue Pour l'écran actuel 
  • Option4: Utilisez une bibliothèque tierce.

Vous trouverez des détails sur ces options ici .

0
Phileo99

Je sais que cette question est assez ancienne, mais j'ai trouvé une solution intéressante . En gros, vous transmettez une présentation de conteneur à cette fonction, qui appliquera la police à toutes les vues prises en charge, et récursivement dans les présentations enfant:

public static void setFont(ViewGroup layout)
{
    final int childcount = layout.getChildCount();
    for (int i = 0; i < childcount; i++)
    {
        // Get the view
        View v = layout.getChildAt(i);

        // Apply the font to a possible TextView
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Apply the font to a possible EditText
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Recursively cicle into a possible child layout
        try {
            ViewGroup vg = (ViewGroup) v;
            Utility.setFont(vg);
            continue;
        }
        catch (Exception e) { }
    }
}
0
FonzTech

pour définir simplement le caractère de l'application sur normal, sans, serif ou monospace (pas avec une police personnalisée!), vous pouvez le faire.

définissez un thème et définissez l'attribut Android:typeface sur le type de caractère que vous souhaitez utiliser dans styles.xml:

<resources>

    <!-- custom normal activity theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- other elements -->
        <item name="Android:typeface">monospace</item>
    </style>

</resources>

appliquez le thème à l'ensemble de l'application dans le fichier AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application
        Android:theme="@style/AppTheme" >
    </application>
</manifest>

Référence Android

0
Eric