web-dev-qa-db-fra.com

Android - Utilisation de la police personnalisée

J'ai appliqué une police personnalisée à une TextView, mais cela ne semble pas changer la police.

Voici mon code:

    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
    TextView myTextView = (TextView)findViewById(R.id.myTextView);
    myTextView.setTypeface(myTypeface);

Est-ce que quelqu'un peut me sortir de ce problème?

255
RATTLESNAKE

Sur Mobiletuts +, il y a un très bon tutoriel sur le formatage de texte pour Android. Astuce: Personnaliser les polices Android

EDIT: Testé moi-même maintenant. Voici la solution. Vous pouvez utiliser un sous-dossier appelé polices, mais il doit figurer dans le dossier assets et non dans le dossier res. Alors

actifs/polices

Assurez-vous également que la police se terminant par Je veux dire que la fin du fichier de police lui-même est en minuscule. En d'autres termes, il ne devrait pas s'agir de myFont.TTF mais de myfont.ttfcette manière doit être en minuscule

226
Octavian Damiean

Après avoir essayé la plupart des solutions décrites dans ce fil de discussion, j'ai découvert accidentellement Calligraphy ( https://github.com/chrisjenx/Calligraphy ) - une bibliothèque de Christopher Jenkins qui vous permet d'ajouter facilement des polices personnalisées à votre application. Les avantages de sa bibliothèque par rapport aux approches suggérées ici sont les suivants:

  1. vous n'êtes pas obligé d'introduire votre propre composant TextView annulé, vous utilisez le TextView intégré 
  2. vous pouvez facilement inclure la bibliothèque en utilisant gradle 
  3. La bibliothèque ne limite pas votre choix de polices; il vous suffit d'ajouter vos préférés à la liste des actifs
  4. vous obtenez non seulement des vues de texte personnalisées - tous les autres composants Android basés sur du texte seront également affichés avec votre police personnalisée.
55
javaxian

Je sais qu'il y a déjà de bonnes réponses, mais voici une mise en œuvre pleinement opérationnelle.

Voici la vue de texte personnalisée:

package com.mycompany.myapp.widget;

/**
 * Text view with a custom font.
 * <p/>
 * In the XML, use something like {@code customAttrs:customFont="roboto-thin"}. The list of fonts
 * that are currently supported are defined in the enum {@link CustomFont}. Remember to also add
 * {@code xmlns:customAttrs="http://schemas.Android.com/apk/res-auto"} in the header.
 */
public class CustomFontTextView extends TextView {

    private static final String sScheme =
            "http://schemas.Android.com/apk/res-auto";
    private static final String sAttribute = "customFont";

    static enum CustomFont {
        ROBOTO_THIN("fonts/Roboto-Thin.ttf"),
        ROBOTO_LIGHT("fonts/Roboto-Light.ttf");

        private final String fileName;

        CustomFont(String fileName) {
            this.fileName = fileName;
        }

        static CustomFont fromString(String fontName) {
            return CustomFont.valueOf(fontName.toUpperCase(Locale.US));
        }

        public Typeface asTypeface(Context context) {
            return Typeface.createFromAsset(context.getAssets(), fileName);
        }
    }

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (isInEditMode()) {
            return;
        } else {
            final String fontName = attrs.getAttributeValue(sScheme, sAttribute);

            if (fontName == null) {
                throw new IllegalArgumentException("You must provide \"" + sAttribute + "\" for your text view");
            } else {
                final Typeface customTypeface = CustomFont.fromString(fontName).asTypeface(context);
                setTypeface(customTypeface);
            }
        }
    }
}

Voici les attributs personnalisés. Cela devrait aller dans votre fichier res/attrs.xml:

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

Et voici comment vous l'utilisez. Je vais utiliser une mise en page relative pour l'envelopper et afficher la déclaration customAttr, mais il peut évidemment s'agir de la mise en page que vous avez déjà.

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:customAttrs="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <com.mycompany.myapp.widget.CustomFontTextView
         Android:layout_width="wrap_content"
         Android:layout_height="wrap_content"
         Android:text="foobar"
         customAttrs:customFont="roboto_thin" />

</RelativeLayout>
32
espinchi

J'ai déjà utilisé cela avec succès. La seule différence entre nos implémentations est que je n'utilisais pas de sous-dossier dans les actifs. Pas sûr que cela change quoi que ce soit, cependant.

14
benvd

À condition que vous ayez placé la police au bon endroit et qu'il n'y ait pas d'erreur dans le fichier de police lui-même, votre code devrait fonctionner comme cela, RATTLESNAKE.

Cependant, ce serait beaucoup plus facile si vous pouviez simplement définir une police dans votre layout XML, comme ceci:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <!-- This text view is styled with the app theme -->
    <com.innovattic.font.FontTextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="This uses my font in bold italic style" />

    <!-- This text view is styled here and overrides the app theme -->
    <com.innovattic.font.FontTextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:flFont="anotherFont"
        Android:textStyle="normal"
        Android:text="This uses another font in normal style" />

    <!-- This text view is styled with a style and overrides the app theme -->
    <com.innovattic.font.FontTextView
        style="@style/StylishFont"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="This also uses another font in normal style" />

</LinearLayout>

Avec le res/values/styles.xml joint:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:Android="http://schemas.Android.com/apk/res/Android" xmlns:tools="http://schemas.Android.com/tools">

    <!-- Application theme -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="AppTheme" parent="Android:Theme.Holo.Light.DarkActionBar">
        <item name="Android:textViewStyle">@style/MyTextViewStyle</item>
    </style>

    <!-- Style to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextViewStyle" parent="@Android:style/Widget.Holo.Light.TextView">
        <item name="Android:textAppearance">@style/MyTextAppearance</item>
    </style>

    <!-- Text appearance to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextAppearance" parent="@Android:style/TextAppearance.Holo">
        <!-- Alternatively, reference this font with the name "aspergit" -->
        <!-- Note that only our own TextView's will use the font attribute -->
        <item name="flFont">someFont</item>
        <item name="Android:textStyle">bold|italic</item>
    </style>

    <!-- Alternative style, maybe for some other widget -->
    <style name="StylishFont">
        <item name="flFont">anotherFont</item>
        <item name="Android:textStyle">normal</item>
    </style>

</resources>

J'ai créé quelques outils spécifiquement à cette fin. Reportez-vous à this project à partir de GitHub, ou jetez un oeil à cet article blog qui explique tout.

14
Jelle Fresen

Pour les polices personnalisées sous Android, créez un dossier dans le dossier assets. Nommez-le "polices" et placez-y le fichier fonts.ttf ou .otf de votre choix.

Si vous étendz UIBaseFragment: 

Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);

sinon si s'étend Activité:

Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);
12
Faakhir

La meilleure façon de le faire À partir de la version d’aperçu d’Android O est la suivante: 

Cela ne fonctionne que si vous avez Android studio-2.4 ou supérieur 

  1. Cliquez avec le bouton droit sur le dossier res et accédez à Nouveau> Répertoire de ressources Android. Le nouveau
    La fenêtre Répertoire de ressources apparaît.
  2. Dans la liste Type de ressource, sélectionnez font, puis cliquez sur OK.
  3. Ajoutez vos fichiers de polices dans le dossier de polices. La structure de dossiers ci-dessous génère R.font.dancing_script, R.font.la_la et R.font.ba_ba.
  4. Double-cliquez sur un fichier de police pour prévisualiser les polices du fichier dans l'éditeur.

Ensuite, nous devons créer une famille de polices:

  1. Cliquez avec le bouton droit sur le dossier de polices et accédez à Nouveau> Fichier de ressources de polices. La fenêtre Nouveau fichier de ressources apparaît.
  2. Entrez le Nom du fichier, puis cliquez sur OK. Le nouveau XML de ressource de police s’ouvre dans l’éditeur.
  3. Incluez chaque fichier de police, style et attribut de poids dans l'élément balise font. Le code XML suivant illustre l’ajout d’attributs liés aux polices dans le code XML de la ressource de police:

Ajout de polices à un TextView:

   <TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:fontFamily="@font/hey_fontfamily"/>

À partir de la documentation 

Travailler avec les polices

Toutes les étapes sont correctes.

11
jeevan s

Vous pouvez utiliser PixlUI à l’adresse https://github.com/neopixl/PixlUI

importer leur .jar et l'utiliser en XML

 <com.neopixl.pixlui.components.textview.TextView
    Android:id="@+id/textView1"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/hello_world"
    pixlui:typeface="GearedSlab.ttf" />
7
guest2343sdfdfs

Comme je n’étais pas satisfait de toutes les solutions présentées sur SO, j’ai proposé la mienne. C’est basé sur un petit truc avec des balises (c’est-à-dire que vous ne pouvez pas utiliser de balises dans votre code), j’ai mis le chemin des polices ici. Ainsi, lors de la définition des vues, vous pouvez faire ceci:

<TextView
        Android:id="@+id/textViewHello1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Hello World 1"
        Android:tag="fonts/Oswald-Regular.ttf"/>

ou ca:

<TextView
        Android:id="@+id/textViewHello2"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Hello World 2"
        style="@style/OswaldTextAppearance"/>

<style name="OswaldTextAppearance">
        <item name="Android:tag">fonts/Oswald-Regular.ttf</item>
        <item name="Android:textColor">#000000</item>
</style>

Maintenant, vous pouvez soit accéder explicitement/configurer la vue en tant que:

TextView textView = TextViewHelper.setupTextView(this, R.id.textViewHello1).setText("blah");

ou simplement tout configurer via:

TextViewHelper.setupTextViews(this, (ViewGroup) findViewById(R.id.parentLayout)); // parentLayout is the root view group (relative layout in my case)

Et quel est le cours de magie que vous demandez? Principalement collés à partir d'autres SO messages, avec des méthodes d'assistance pour l'activité et les fragments:

import Android.app.Activity;
import Android.content.Context;
import Android.graphics.Typeface;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;

import Java.util.HashMap;
import Java.util.Map;

public class TextViewHelper {
    private static final Map<String, Typeface> mFontCache = new HashMap<>();

    private static Typeface getTypeface(Context context, String fontPath) {
        Typeface typeface;
        if (mFontCache.containsKey(fontPath)) {
            typeface = mFontCache.get(fontPath);
        } else {
            typeface = Typeface.createFromAsset(context.getAssets(), fontPath);
            mFontCache.put(fontPath, typeface);
        }
        return typeface;
    }

    public static void setupTextViews(Context context, ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setupTextViews(context, (ViewGroup) child);
            } else {
                if (child != null) {
                    TextViewHelper.setupTextView(context, child);
                }
            }
        }
    }

    public static void setupTextView(Context context, View view) {
        if (view instanceof TextView) {
            if (view.getTag() != null) // also inherited from TextView's style
            {
                TextView textView = (TextView) view;
                String fontPath = (String) textView.getTag();
                Typeface typeface = getTypeface(context, fontPath);
                if (typeface != null) {
                    textView.setTypeface(typeface);
                }
            }
        }
    }

    public static TextView setupTextView(View rootView, int id) {
        TextView textView = (TextView) rootView.findViewById(id);
        setupTextView(rootView.getContext().getApplicationContext(), textView);
        return textView;
    }

    public static TextView setupTextView(Activity activity, int id) {
        TextView textView = (TextView) activity.findViewById(id);
        setupTextView(activity.getApplicationContext(), textView);
        return textView;
    }
}
4
Miro Kropacek

Malheureusement, il n'y a pas de bonne solution pour cela.

J'ai vu de nombreux articles sur l'utilisation d'un TextView personnalisé, mais ils l'oublient, à savoir que ce ne sont pas seulement les textviews qui peuvent implémenter des polices et qu'il y en a cachés dans d'autres vues inaccessibles au développeur; Je ne vais même pas me lancer sur Spannable.

Vous pouvez utiliser un utilitaire de polices externe tel que:

Calligraphie Font Tool

MAIS Ceci parcourt toutes les vues de l'application lors de sa création et même cet utilitaire manque quelques vues (ViewPager rend la police normale). Vous rencontrez le problème qui se produit lorsque Google met à jour ses outils de génération doit cibler des propriétés obsolètes. C'est aussi un peu lent car il utilise Java's Reflection.

C'est vraiment à Google de résoudre ce problème. Nous avons besoin d'une meilleure prise en charge des polices sous Android. Si vous regardez la solution d'iOS, ils ont littéralement une centaine de polices intégrées. Vous voulez une police personnalisée? Il suffit de déposer une TFF et c'est utilisable ..

Pour le moment, nous nous sommes limités à l'offre proposée par Google, extrêmement limitée mais heureusement optimisée pour les mobiles.

4
Oliver Dixon

Avec Android 8.0, utiliser des polices personnalisées dans Application est devenu facile avec downloadable fonts. Nous pouvons ajouter des polices directement au res/font/ folder dans le dossier du projet, ce qui les rend automatiquement disponibles dans Android Studio. .

 Folder Under res with name font and type set to Font

Maintenant, définissez l'attribut fontFamily sur la liste des polices ou cliquez sur plus et sélectionnez la police de votre choix. Ceci va ajouter la ligne tools:fontFamily="@font/your_font_file" à votre TextView.

Ceci générera automatiquement quelques fichiers.

1. Dans le dossier de valeurs, il créera fonts_certs.xml.

2. Dans Manifest, il ajoutera les lignes suivantes:

  <meta-data
            Android:name="preloaded_fonts"
            Android:resource="@array/preloaded_fonts" /> 

3.preloaded_fonts.xml

<resources>
    <array name="preloaded_fonts" translatable="false">
        <item>@font/open_sans_regular</item>
        <item>@font/open_sans_semibold</item>
    </array>
</resources>
2
Dipali s.

Assurez-vous de coller le code ci-dessus dans onCreate () after votre appel au super et l’appel à setContentView (). Ce petit détail m'a gardé suspendu pendant un moment.

2
Jaxon

Si vous souhaitez charger la police à partir du réseau ou la styler facilement, vous pouvez utiliser:

https://github.com/shellum/fontView

Exemple:

<!--Layout-->
<com.finalhack.fontview.FontView
        Android:id="@+id/someFontIcon"
        Android:layout_width="80dp"
        Android:layout_height="80dp" />

//Java:
fontView.setupFont("http://blah.com/myfont.ttf", true, character, FontView.ImageType.CIRCLE);
fontView.addForegroundColor(Color.RED);
fontView.addBackgroundColor(Color.WHITE);
1
Shellum

Après sept ans, vous pouvez modifier l’application entière textView ou ce que vous voulez facilement à l’aide des bibliothèques Android.support 26 ++.

Par exemple:

Créez votre paquet de polices app/src/res/font et déplacez-y votre police.

 enter image description here

Et dans le thème de votre application, ajoutez-le simplement en tant que fontFamily:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
   . . . ...
    <item name="Android:fontFamily">@font/demo</item>
</style>

Exemple à utiliser avec textView uniquement:

<style name="fontTextView" parent="@Android:style/Widget.TextView">
    <item name="Android:fontFamily">monospace</item>
</style>

Et ajoutez dans votre thème principal:

<item name="Android:textViewStyle">@style/fontTextView</item>

Actuellement, il fonctionne sur 8.1 jusqu'à la version 4.1 de l'API Jelly Bean et c'est une gamme étendue.

1
user6490462

J'ai eu le même problème, le TTF ne s'est pas présenté. J'ai changé le fichier de police, et avec le même code, ça marche. 

1

Vous pouvez utiliser la bibliothèque easy & simple EasyFonts / tierce pour définir diverses polices personnalisées sur votre TextView. En utilisant cette bibliothèque, vous ne devriez pas avoir à vous soucier du téléchargement et de l'ajout de polices dans le dossier assets/fonts. Également à propos de la création d’objet Police.

Au lieu de

Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(myTypeface);

Simplement:

TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(EasyFonts.robotoThin(this));

Cette bibliothèque fournit également le caractère de police suivant.

  • Roboto
  • Droid Serif
  • Robot Droid
  • Liberté
  • Fun Raiser
  • Nation Android
  • Avocat vert
  • Reconnaissance
1
vsvankhede

Réponse mise à jour: Android 8.0 (API niveau 26) introduit une nouvelle fonctionnalité, les polices en XML . Il suffit d'utiliser la fonctionnalité Polices en XML sur les appareils exécutant Android 4.1 (API niveau 16) et les versions ultérieures, utilisez la bibliothèque de support 26. 

voir ce link


Ancienne réponse

Il existe deux façons de personnaliser les polices:

!!! ma police personnalisée dans assets/fonts/iran_sans.ttf



Voie 1: Refrection Typeface.class ||| meilleur moyen

appel FontsOverride.setDefaultFont () dans la classe étend Application. Ce code entraîne la modification de toutes les polices logicielles, même des polices Toasts. 

AppController.Java

public class AppController extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");

    }
}

FontsOverride.Java

public class FontsOverride {

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

    private 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();
        }
    }
}



Voie 2: utilise setTypeface

pour une vue spéciale, appelez simplement setTypeface () pour changer de police.

CTextView.Java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.Lollipop)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.Java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}
1
Rasoul Miri
  • Ouvrez votre projet et sélectionnez Projet en haut à gauche
  • app -> src -> main 
  • faites un clic droit sur main et créez un répertoire nommé assets
  • clic droit pour tester et créer un nouveau répertoire nommé fonts
  • vous devez trouver des polices gratuites telles que polices gratuites
  • donnez-le à votre Textview et appelez-le dans votre classe d'activité
  • copier vos polices dans le dossier fonts
  • TextView txt = (TextView) findViewById(R.id.txt_act_spalsh_welcome); Typeface font = Typeface.createFromAsset(getAssets(), "fonts/Aramis Italic.ttf"); txt.setTypeface(font);

le nom de la police doit être correct et amusant

0
Sam

La solution la plus simple Android supporté maintenant! 

Utiliser une police personnalisée en xml:

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:fontFamily="@font/[your font resource]"/>

regarder les détails:

https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

0
mrtwo

Oui, les polices téléchargeables sont si faciles, comme Dipali s dit.

Voici comment tu le fais ...

  1. Placez une TextView.
  2. Dans le volet des propriétés, sélectionnez la liste déroulante fontFamily. Si ce n'est pas là, recherchez le truc caret (le> et cliquez dessus pour développer textAppearance) sous le.
  3. Développez la liste déroulante font-family.
  4. Dans la petite liste, faites défiler l'écran jusqu'en bas pour afficher more fonts
  5. Cela ouvrira une boîte de dialogue dans laquelle vous pouvez rechercher à partir de Google Fonts
  6. Recherchez la police que vous aimez avec la barre de recherche en haut.
  7. Sélectionnez votre police.
  8. Sélectionnez le style de police que vous aimez (gras, normal, italique, etc.)
  9. Dans le volet de droite, choisissez le bouton radio Add font to project.
  10. Cliquez d'accord. Maintenant, votre TextView a la police que vous aimez!

BONUS: Si vous souhaitez styler TOUT avec du texte dans votre application avec la police choisie, ajoutez simplement <item name="Android:fontfamily">@font/fontnamehere</item> à votre styles.xml

0
flash76

La manière correcte de procéder à partir de l'API 26 est décrite dans la documentation officielle ici:

https://developer.Android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

Cela implique de placer les fichiers ttf dans le dossier res/font et de créer un fichier de familles de polices.

0
Das