Comment changer la police sur le TextView?


Réponses:


342

Tout d'abord, la valeur par défaut n'est pas Arial. La valeur par défaut est Droid Sans.

Deuxièmement, pour passer à une autre police intégrée, utilisez la android:typefacemise en page XML ou setTypeface()Java.

Troisièmement, il n'y a pas de police Helvetica dans Android. Les choix intégrés sont Droid Sans ( sans), Droid Sans Mono ( monospace) et Droid Serif ( serif). Bien que vous puissiez regrouper vos propres polices avec votre application et les utiliser via setTypeface(), gardez à l'esprit que les fichiers de polices sont volumineux et, dans certains cas, nécessitent des accords de licence (par exemple, Helvetica, une police Linotype ).

ÉDITER

Le langage de conception Android repose sur des outils typographiques traditionnels tels que l'échelle, l'espace, le rythme et l'alignement avec une grille sous-jacente. Le déploiement réussi de ces outils est essentiel pour aider les utilisateurs à comprendre rapidement un écran d'informations. Pour prendre en charge une telle utilisation de la typographie, Ice Cream Sandwich a introduit une nouvelle famille de types nommée Roboto, créée spécifiquement pour les exigences de l'interface utilisateur et des écrans haute résolution.

Le cadre TextView actuel offre Roboto dans des poids minces, légers, réguliers et gras, ainsi qu'un style italique pour chaque poids. Le cadre propose également la variante Roboto Condensed dans des poids réguliers et gras, ainsi qu'un style italique pour chaque poids.

Après ICS, Android inclut le style de polices Roboto, En savoir plus Roboto

EDIT 2

Avec l'avènement de la bibliothèque de support 26, Android prend désormais en charge les polices personnalisées par défaut. Vous pouvez insérer de nouvelles polices dans res / fonts qui peuvent être définies individuellement sur TextViews en XML ou par programme. La police par défaut pour toute l'application peut également être modifiée en la définissant styles.xml La documentation pour les développeurs Android contient un guide clair à ce sujet ici


6
Pas moyen de définir des polices en XML? Pourquoi?
Jonny

5
@Jonny Vous pouvez réellement. Vous créez une classe qui étend TextView et appelle setTypeface à partir du constructeur.
Mark Phillip

comment faire dans XML Layout?
M. Usman Khan

2
@usman: Vous auriez besoin d' une bibliothèque tierce, comme la calligraphie: github.com/chrisjenx/Calligraphy
CommonsWare

La définition de la police de caractères à l'aide du code java est difficile en raison de plusieurs lignes, j'ai créé une bibliothèque pour définir des polices personnalisées. Vous pouvez trouver une utilisation de la bibliothèque dans cette réponse stackoverflow.com/a/42001474/4446392
Chathura Jayanath

254

Téléchargez d'abord le .ttffichier de la police dont vous avez besoin ( arial.ttf). Placez-le dans le assets dossier. (Dans le dossier des ressources, créez un nouveau dossier nommé polices et placez-le à l'intérieur.) Utilisez le code suivant pour appliquer la police à votre TextView:

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);

Cher Mayur, Une recommandation sur où obtenir ces fichiers .ttf?
lonelearner

3
Cher @lonelearner, vous pouvez télécharger des fichiers de polices gratuites (.ttf) dans 1001freefonts.com ou simplement google "Free fonts"
ymerdrengene

10
Pour ceux qui utilisent Android Studio et ne trouvent pas de dossier "actifs", consultez cette question . Réponse courte: src/main/assets/fonts/.
adamdport

51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);

33

Vous voudrez peut-être créer une classe statique qui contiendra toutes les polices. De cette façon, vous ne créerez pas la police plusieurs fois, ce qui pourrait avoir un impact négatif sur les performances . Assurez-vous simplement de créer un sous-dossier appelé " polices " sous " ressources " dossier ".

Faites quelque chose comme:

public class CustomFontsLoader {

public static final int FONT_NAME_1 =   0;
public static final int FONT_NAME_2 =   1;
public static final int FONT_NAME_3 =   2;

private static final int NUM_OF_CUSTOM_FONTS = 3;

private static boolean fontsLoaded = false;

private static Typeface[] fonts = new Typeface[3];

private static String[] fontPath = {
    "fonts/FONT_NAME_1.ttf",
    "fonts/FONT_NAME_2.ttf",
    "fonts/FONT_NAME_3.ttf"
};


/**
 * Returns a loaded custom font based on it's identifier. 
 * 
 * @param context - the current context
 * @param fontIdentifier = the identifier of the requested font
 * 
 * @return Typeface object of the requested font.
 */
public static Typeface getTypeface(Context context, int fontIdentifier) {
    if (!fontsLoaded) {
        loadFonts(context);
    }
    return fonts[fontIdentifier];
}


private static void loadFonts(Context context) {
    for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
        fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
    }
    fontsLoaded = true;

}
}

De cette façon, vous pouvez obtenir la police de partout dans votre application.


1
Génial frérot! Telle est la beauté de la POO. Bon travail! :)
Joshua Michael Waggoner

Comment utiliser cette classe?
Jack

Vous devez placer ce code dans votre projet, l'adapter à vos polices, puis utiliser la méthode statique getTypeface (..) de partout dans votre application.
Daniel L.

J'ai utilisé une solution similaire, mais j'ai ajouté la mise en cache pour améliorer les performances .... dans tous les cas, avez-vous rencontré une situation où la police fonctionne sur certains téléphones et pas dans d'autres?
RJFares

20

Les meilleures pratiques de tous les temps

TextViewPlus.java:

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

    public TextViewPlus(Context context) {
        super(context);
    }

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface typeface = null;
        try {
            typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
        } catch (Exception e) {
            Log.e(TAG, "Unable to load typeface: "+e.getMessage());
            return false;
        }

        setTypeface(typeface);
        return true;
    }
}

attrs.xml: (Où placer res / valeurs )

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TextViewPlus">
        <attr name="customFont" format="string"/>
    </declare-styleable>
</resources>

Comment utiliser:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.mypackage.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="my_font_name_regular.otf">
    </com.mypackage.TextViewPlus>
</LinearLayout>

J'espère que ceci vous aidera.


1
Pourquoi le sous-classement de TextView est-il la meilleure pratique?
Stealth Rabbi

@Stealth Rabbi, ici nous pouvons passer des polices personnalisées uniquement en XML, pas besoin d'écrire du code Java spécial pour chaque affichage de texte.
Hiren Patel

Il y a une bibliothèque pour ça. Ajoutez simplement votre police sous le dossier des ressources et déclarez-la en XML. github.com/febaisi/CustomTextView
febaisi

Votre bibliothèque semble bien, mais le seul problème est qu'elle est pour Android 21+
loloof64


17

Les réponses ci-dessus sont correctes. Assurez-vous simplement de créer un sous-dossier appelé "polices" sous le dossier "actifs" si vous utilisez ce morceau de code.


1
Votre commentaire est redondant. L'explication ci-dessus dit exactement ce que vous avez dit, et plus ...
Joshua Michael Waggoner

14

Une autre façon de consolider la création de polices ...

public class Font {
  public static final Font  PROXIMA_NOVA    = new Font("ProximaNovaRegular.otf");
  public static final Font  FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
  private final String      assetName;
  private volatile Typeface typeface;

  private Font(String assetName) {
    this.assetName = assetName;
  }

  public void apply(Context context, TextView textView) {
    if (typeface == null) {
      synchronized (this) {
        if (typeface == null) {
          typeface = Typeface.createFromAsset(context.getAssets(), assetName);
        }
      }
    }
    textView.setTypeface(typeface);
  }
}

Et puis à utiliser dans votre activité ...

myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);

Attention, cet idiome de verrouillage à double vérification avec le champ volatile ne fonctionne correctement qu'avec le modèle de mémoire utilisé dans Java 1.5+.


Pourquoi cette réponse a-t-elle seulement 1 vote positif et celle ci-dessus en a 15? Qu'est-ce qui rend l'autre meilleur? Il me semble que celui-ci est le plus simple en utilisant le principe singleton ...?
Koen Demonie

Je viens de voir que vous avez votre constructeur public, je le rendrais privé car vous n'avez pas besoin d'y accéder. Vous utilisez vos polices internes de toute façon ...
Koen Demonie

Absolument devrait être un constructeur privé. Bien repéré :) éditera!
Chris Aitchison

12

La meilleure pratique consiste à utiliser la bibliothèque de support Android version 26.0.0 ou supérieure.

ÉTAPE 1: ajouter un fichier de police

  1. Dans le dossier res , créez une nouvelle police dictionnaire de ressources de
  2. Ajouter un fichier de police ( .ttf , .orf )

Par exemple, lorsque le fichier de police sera helvetica_neue.ttf qui générera R.font.helvetica_neue

ÉTAPE 2: créer une famille de polices

  1. Dans la police dossier des , ajoutez un nouveau fichier de ressources
  2. Joignez chaque fichier de police, style et attribut d'épaisseur à l'élément.

Par exemple:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/helvetica_neue" />
</font-family>

ÉTAPE 3: utilisez-le

Dans les présentations XML:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/my_font"/>

Ou ajoutez des polices au style:

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

Pour plus d'exemples, vous pouvez suivre la documentation:

Travailler avec des polices


7

C'est un peu vieux, mais j'ai amélioré un peu la classe CustomFontLoader et je voulais la partager pour qu'elle puisse être utile. Créez simplement une nouvelle classe avec ce code.

 import android.content.Context;
 import android.graphics.Typeface;

public enum FontLoader {

ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");   


private final String name;
private Typeface typeFace;


private FontLoader(final String name) {
    this.name = name;

    typeFace=null;  
}

public static Typeface getTypeFace(Context context,String name){
    try {
        FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
        if(item.typeFace==null){                
            item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");                 
        }           
        return item.typeFace;
    } catch (Exception e) {         
        return null;
    }                   
}
public static Typeface getTypeFace(Context context,int id){
    FontLoader myArray[]= FontLoader.values();
    if(!(id<myArray.length)){           
        return null;
    } 
    try {
        if(myArray[id].typeFace==null){     
            myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");                       
        }       
        return myArray[id].typeFace;    
    }catch (Exception e) {          
        return null;
    }   

}

public static Typeface getTypeFaceByName(Context context,String name){      
    for(FontLoader item: FontLoader.values()){              
        if(name.equalsIgnoreCase(item.name)){
            if(item.typeFace==null){
                try{
                    item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
                }catch (Exception e) {          
                    return null;
                }   
            }
            return item.typeFace;
        }               
    }
    return null;
}   

public static void loadAllFonts(Context context){       
    for(FontLoader item: FontLoader.values()){              
        if(item.typeFace==null){
            try{
                item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
            }catch (Exception e) {
                item.typeFace=null;
            }   
        }                
    }       
}   
}

Ensuite, utilisez simplement ce code sur votre affichage de texte:

 Typeface typeFace=FontLoader.getTypeFace(context,"arial");  
 if(typeFace!=null) myTextView.setTypeface(typeFace);

5

J'ai finalement obtenu une solution très simple à cela.

  1. utilisez ces bibliothèques de support dans le niveau d'application ,

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. puis créez un répertoire nommé "police" dans le dossier res

  3. placez les fichiers de polices (ttf) dans ce répertoire de polices, gardez à l'esprit les conventions de dénomination [par exemple, le nom ne doit contenir aucun caractère spécial, aucun caractère majuscule et aucun espace ou tabulation]
  4. Après cela, référencez cette police de XML comme ceci

            <Button
            android:id="@+id/btn_choose_employee"
            android:layout_width="140dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:background="@drawable/rounded_red_btn"
            android:onClick="btnEmployeeClickedAction"
            android:text="@string/searching_jobs"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:fontFamily="@font/times_new_roman_test"
            />

Dans cet exemple, times_new_roman_test est un fichier ttf de police de ce répertoire de police


4
import java.lang.ref.WeakReference;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Typeface;

public class FontsManager {

    private static FontsManager instance;

    private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();

    private static Context context;

    private FontsManager(final Context ctx) {
        if (context == null) {
            context = ctx;
        }
    }

    public static FontsManager getInstance(final Context appContext) {
        if (instance == null) {
            instance = new FontsManager(appContext);
        }
        return instance;
    }

    public static FontsManager getInstance() {
        if (instance == null) {
            throw new RuntimeException(
                    "Call getInstance(Context context) at least once to init the singleton properly");
        }
        return instance;
    }

    public Typeface getFont(final String assetName) {
        final WeakReference<Typeface> tfReference = typefaces.get(assetName);
        if (tfReference == null || tfReference.get() == null) {
            final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
                    assetName);
            typefaces.put(assetName, new WeakReference<Typeface>(tf));
            return tf;
        }
        return tfReference.get();
    }

}

De cette façon, vous pouvez créer une vue qui hérite de TextView et appelle setTypeface sur son constructeur.


1
Bonjour, pourquoi utilisez WeakReference pour contenir un objet TypeFace?
Lazy

3

Lorsque votre police est stockée à l'intérieur, res/asset/fonts/Helvetica.ttfutilisez ce qui suit:

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf"); 
txt.setTypeface(tf);

Ou, si votre fichier de polices est stocké à l'intérieur, res/font/helvetica.ttfutilisez ce qui suit:

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);

2
Merci, vous cherchiez la partie où vous l'aviez dans le dossier res!
Mikkel Larsen

2

obtenir la police de l'actif et définir pour tous les enfants

public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
         }
        } else if (v instanceof TextView ) {
            ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
        }
    } catch (Exception e) {
 }
 } 

2
  1. ajoutez la classe FontTextView.java:


public class FontTextView extends TextView {
    String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};

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

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

    }

    public FontTextView(Context context) {
        super(context);
        if (!isInEditMode()) {
            init(null);
        }
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
            if (a.getString(R.styleable.FontTextView_font_type) != null) {
                String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];

                if (fontName != null) {
                    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
                    setTypeface(myTypeface);
                }
                a.recycle();
            }
        }
    }
}


  1. ajouter à la police de la bibliothèque de ressources
    entrez la description de l'image ici


  1. ajouter à attrs.xml, les nombres doivent être dans l'ordre dans la classe de tableau.

    <declare-styleable name="FontTextView">
    <attr name="font_type" format="enum">
        <enum name="HelveticaNeue" value="0"/>
        <enum name="HelveticaNeueLight" value="1"/>
        <enum name="motschcc" value="2"/>
        <enum name="symbol" value="3"/>
    </attr>


  1. Sélectionnez une police dans la liste
    entrez la description de l'image ici

Avez-vous besoin d'instancier cette classe dans MainActivity? Parce que ça ne change rien pour moi.
Tobias Mayr

1

Android utilise la police Roboto, qui est une police très agréable à regarder, avec plusieurs poids différents (régulier, léger, fin, condensé) qui ont fière allure sur les écrans haute densité.

Vérifiez le lien ci-dessous pour vérifier les polices roboto:

Comment utiliser Roboto dans une mise en page XML

Revenons à votre question, si vous souhaitez modifier la police de tous les TextView / Button dans votre application , essayez d'ajouter le code ci-dessous dans votre styles.xml pour utiliser la police Roboto-light :

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ......
    <item name="android:buttonStyle">@style/MyButton</item>
    <item name="android:textViewStyle">@style/MyTextView</item>
</style>

<style name="MyButton" parent="@style/Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

Et n'oubliez pas d'utiliser 'AppTheme' dans votre AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ......
</application>

0

Peut-être quelque chose d'un peu plus simple:

public class Fonts {
  public static HashSet<String,Typeface> fonts = new HashSet<>();

  public static Typeface get(Context context, String file) {
    if (! fonts.contains(file)) {
      synchronized (this) {
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
        fonts.put(name, typeface);
      }
    }
    return fonts.get(file);
  }
}

// Usage
Typeface myFont = Fonts.get("arial.ttf");

(Notez que ce code n'est pas testé, mais en général, cette approche devrait bien fonctionner.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.