web-dev-qa-db-fra.com

Utiliser un caractère personnalisé dans Android

Je souhaite utiliser une police personnalisée pour mon application Android que je crée.
Je peux modifier individuellement la police de caractères de chaque objet à partir de Code, mais j'en ai des centaines.

Alors,

  • Y at-il un moyen de faire cela à partir du XML? [Définition d'un caractère personnalisé]
  • Existe-t-il un moyen de procéder à partir d'un code situé au même endroit, en indiquant que l'ensemble de l'application et tous les composants doivent utiliser la police de caractères personnalisée au lieu de celle par défaut?
110
Codevalley

Y a-t-il un moyen de faire cela depuis le XML?

Non désolé. Vous pouvez uniquement spécifier les polices de caractères intégrées via XML.

Y a-t-il un moyen de le faire depuis code in un endroit, pour dire que le tout application et tous les composants devrait utiliser le caractère personnalisé à la place de celui par défaut?

Pas que je sache.

Il existe une variété d'options pour ces derniers:

  • Ressources de polices et backports dans le SDK Android, si vous utilisez appcompat

  • Bibliothèques tierces pour ceux qui n'utilisent pas appcompat, bien que tous ne supportent pas la définition de la police dans les ressources de présentation

82
CommonsWare

Oui c'est possible.

Vous devez créer une vue personnalisée qui étend la vue texte.

Dans attrs.xml dans le dossier values:

<resources>
    <declare-styleable name="MyTextView">
        <attr name="first_name" format="string"/>
        <attr name="last_name" format="string"/>
        <attr name="ttf_name" format="string"/>
    </declare-styleable>
</resources>

Dans main.xml:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
     xmlns:lht="http://schemas.Android.com/apk/res/com.lht"
    Android:orientation="vertical"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    >
    <TextView  Android:layout_width="fill_parent" 
        Android:layout_height="wrap_content"
        Android:text="Hello"/>
    <com.lht.ui.MyTextView  
        Android:id="@+id/MyTextView"
        Android:layout_width="fill_parent" 
        Android:layout_height="wrap_content"
        Android:text="Hello friends"
        lht:ttf_name="ITCBLKAD.TTF"
        />   
</LinearLayout>

Dans MyTextView.Java:

package com.lht.ui;

import Android.content.Context;
import Android.graphics.Typeface;
import Android.util.AttributeSet;
import Android.util.Log;
import Android.widget.TextView;

public class MyTextView extends TextView {

    Context context;
    String ttfName;

    String TAG = getClass().getName();

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;

        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            Log.i(TAG, attrs.getAttributeName(i));
            /*
             * Read value of custom attributes
             */

            this.ttfName = attrs.getAttributeValue(
                    "http://schemas.Android.com/apk/res/com.lht", "ttf_name");
            Log.i(TAG, "firstText " + firstText);
            // Log.i(TAG, "lastText "+ lastText);

            init();
        }

    }

    private void init() {
        Typeface font = Typeface.createFromAsset(context.getAssets(), ttfName);
        setTypeface(font);
    }

    @Override
    public void setTypeface(Typeface tf) {

        // TODO Auto-generated method stub
        super.setTypeface(tf);
    }

}
109
Manish Singla

Je l'ai fait d'une manière plus "brutale" qui ne nécessite aucune modification de la mise en page xml ni des activités. 

Testé sur les versions Android 2.1 à 4.4. Exécutez ceci au démarrage de l'application, dans votre classe d'application: 

private void setDefaultFont() {

    try {
        final Typeface bold = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_FONT_FILENAME);
        final Typeface italic = Typeface.createFromAsset(getAssets(), DEFAULT_ITALIC_FONT_FILENAME);
        final Typeface boldItalic = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_ITALIC_FONT_FILENAME);
        final Typeface regular = Typeface.createFromAsset(getAssets(),DEFAULT_NORMAL_FONT_FILENAME);

        Field DEFAULT = Typeface.class.getDeclaredField("DEFAULT");
        DEFAULT.setAccessible(true);
        DEFAULT.set(null, regular);

        Field DEFAULT_BOLD = Typeface.class.getDeclaredField("DEFAULT_BOLD");
        DEFAULT_BOLD.setAccessible(true);
        DEFAULT_BOLD.set(null, bold);

        Field sDefaults = Typeface.class.getDeclaredField("sDefaults");
        sDefaults.setAccessible(true);
        sDefaults.set(null, new Typeface[]{
                regular, bold, italic, boldItalic
        });

    } catch (NoSuchFieldException e) {
        logFontError(e);
    } catch (IllegalAccessException e) {
        logFontError(e);
    } catch (Throwable e) {
        //cannot crash app if there is a failure with overriding the default font!
        logFontError(e);
    }
}

Pour un exemple plus complet, voir http://github.com/perchrh/FontOverrideExample

49
P-chan

Bien que je vote la réponse de Manish comme la méthode la plus rapide et la plus ciblée, j'ai également vu des solutions naïves qui ne font qu'itérer récursivement à travers une hiérarchie de vues et mettre à jour les polices de tous les éléments. Quelque chose comme ça:

public static void applyFonts(final View v, Typeface fontToSet)
{
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                applyFonts(child, fontToSet);
            }
        } else if (v instanceof TextView) {
            ((TextView)v).setTypeface(fontToSet);
        }
    } catch (Exception e) {
        e.printStackTrace();
        // ignore
    }
}

Vous devez appeler cette fonction sur vos vues après avoir gonflé la présentation et dans les méthodes onContentChanged() de votre activité.

36
pospi

J'ai pu le faire de manière centralisée, voici le résultat:

enter image description here

J'ai Activity et je l'étends si j'ai besoin de polices personnalisées:

import Android.app.Activity;
import Android.content.Context;
import Android.os.Bundle;
import Android.util.AttributeSet;
import Android.view.LayoutInflater.Factory;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.widget.TextView;

public class CustomFontActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    getLayoutInflater().setFactory(new Factory() {

        @Override
        public View onCreateView(String name, Context context,
                AttributeSet attrs) {
            View v = tryInflate(name, context, attrs);
            if (v instanceof TextView) {
                setTypeFace((TextView) v);
            }
            return v;
        }
    });
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs); 
    } catch (Exception e) {
        try {
            v = li.createView("Android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

Mais si j'utilise une activité du package de support, par exemple FragmentActivity alors j'utilise cette Activity

import Android.annotation.TargetApi;
import Android.content.Context;
import Android.os.Build;
import Android.os.Bundle;
import Android.support.v4.app.FragmentActivity;
import Android.util.AttributeSet;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.widget.TextView;

public class CustomFontFragmentActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

// we can't setLayout Factory as its already set by FragmentActivity so we
// use this approach
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
    View v = super.onCreateView(name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(View parent, String name, Context context,
        AttributeSet attrs) {
    View v = super.onCreateView(parent, name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs);
    } catch (Exception e) {
        try {
            v = li.createView("Android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

Je n'ai pas encore testé ce code avec Fragments, mais j'espère que cela fonctionnera. 

Ma FontUtils est simple, ce qui résout également le problème pré-ICS mentionné ici https://code.google.com/p/Android/issues/detail?id=9904 :

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

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

public class FontUtils {

private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

public static Typeface getFonts(Context context, String name) { 
    Typeface typeface = TYPEFACE.get(name);
    if (typeface == null) {
        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
                + name);
        TYPEFACE.put(name, typeface);
    }
    return typeface;
}
}
23
M-WaJeEh

Hé, j'ai aussi besoin de 2 polices différentes dans mon application pour différents widgeds! J'utilise cette méthode:

Dans ma classe d'application, je crée une méthode statique:

public static Typeface getTypeface(Context context, String typeface) {
    if (mFont == null) {
        mFont = Typeface.createFromAsset(context.getAssets(), typeface);
    }
    return mFont;
}

La police de caractères String représente le fichier xyz.ttf dans le dossier des ressources. (J'ai créé une classe de constantes) Vous pouvez maintenant l'utiliser partout dans votre application:

mTextView = (TextView) findViewById(R.id.text_view);
mTextView.setTypeface(MyApplication.getTypeface(this, Constants.TYPEFACE_XY));

Le seul problème est que vous en avez besoin pour chaque widget pour lequel vous souhaitez utiliser la police! Mais je pense que c'est la meilleure solution.

10
Informatic0re

J'ai trouvé une solution intéressante sur le blog de Lisa Wray . Avec la nouvelle liaison de données, il est possible de définir la police dans vos fichiers XML.

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
    textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

En XML:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"/>
4
userM1433372

En utilisant la suggestion de pospi et en utilisant la propriété 'tag' comme Richard, j'ai créé une classe personnalisée qui charge mes polices personnalisées et les applique aux vues en fonction de leurs balises.

Donc, fondamentalement, au lieu de définir TypeFace dans l'attribut Android: fontFamily, vous utilisez Android: tag attritube et définissez-le sur l'un des énumérations définies.

public class Fonts {
    private AssetManager mngr;

    public Fonts(Context context) {
        mngr = context.getAssets();
    }
    private enum AssetTypefaces {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    private Typeface getTypeface(AssetTypefaces font) {
        Typeface tf = null;
        switch (font) {
            case RobotoLight:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Light.ttf");
                break;
            case RobotoThin:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Thin.ttf");
                break;
            case RobotoCondensedBold:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Bold.ttf");
                break;
            case RobotoCondensedLight:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Light.ttf");
                break;
            case RobotoCondensedRegular:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Regular.ttf");
                break;
            default:
                tf = Typeface.DEFAULT;
                break;
        }
        return tf;
    }
    public void setupLayoutTypefaces(View v) {
        try {
            if (v instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            } else if (v instanceof TextView) {
                if (v.getTag().toString().equals(AssetTypefaces.RobotoLight.toString())){
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedRegular.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedRegular));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedBold.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedBold));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedLight.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoThin.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoThin));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            // ignore
        }
    }
}

Dans votre activité ou votre fragment, il vous suffit d'appeler

Fonts fonts = new Fonts(getActivity());
fonts.setupLayoutTypefaces(mainLayout);
4
majinboo

Je pense qu'il peut y avoir un moyen plus pratique de le faire. La classe suivante définira un type personnalisé pour tous les composants de votre application (avec un paramètre par classe).

/**
 * Base Activity of our app hierarchy.
 * @author SNI
 */
public class BaseActivity extends Activity {

    private static final String FONT_LOG_CAT_TAG = "FONT";
    private static final boolean ENABLE_FONT_LOGGING = false;

    private Typeface helloTypeface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        helloTypeface = Typeface.createFromAsset(getAssets(), "fonts/<your type face in assets/fonts folder>.ttf");
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(parent, name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    protected View setCustomTypeFaceIfNeeded(String name, AttributeSet attrs, View view) {
        View result = null;
        if ("TextView".equals(name)) {
            result = new TextView(this, attrs);
            ((TextView) result).setTypeface(helloTypeface);
        }

        if ("EditText".equals(name)) {
            result = new EditText(this, attrs);
            ((EditText) result).setTypeface(helloTypeface);
        }

        if ("Button".equals(name)) {
            result = new Button(this, attrs);
            ((Button) result).setTypeface(helloTypeface);
        }

        if (result == null) {
            return view;
        } else {
            if (ENABLE_FONT_LOGGING) {
                Log.v(FONT_LOG_CAT_TAG, "A type face was set on " + result.getId());
            }
            return result;
        }
    }

}
3
Snicolas

Les implémentations par défaut de LayoutInflater ne prennent pas en charge la spécification du caractère de police à partir de xml. Je l’ai cependant vu faire en XML en fournissant une fabrique personnalisée pour LayoutInflater qui analysera ces attributs à partir de la balise xml.

La structure de base aimerait ceci.

public class TypefaceInflaterFactory implements LayoutInflater.Factory {

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        // CUSTOM CODE TO CREATE VIEW WITH TYPEFACE HERE
        // RETURNING NULL HERE WILL TELL THE INFLATER TO USE THE
        // DEFAULT MECHANISMS FOR INFLATING THE VIEW FROM THE XML
    }

}

public class BaseActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater.from(this).setFactory(new TypefaceInflaterFactory());
    }
}

Cet article fournit une explication plus détaillée de ces mécanismes et explique comment l'auteur tente de fournir un support de mise en page XML pour les polices de caractères de cette manière. Le code pour l'implémentation de l'auteur peut être trouvé ici .

2
Ryan Thomas

Oui, c'est possible en remplaçant la police de caractères par défaut . J'ai suivi this solution et cela a fonctionné comme un charme pour tous les textes de TextViews et ActionBar avec un seul changement.

public class MyApp extends Application {

  @Override
  public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
  }
}

styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/pantone</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="Android:windowTranslucentStatus" tools:targetApi="KitKat">true</item>
    <item name="Android:windowDisablePreview">true</item>
    <item name="Android:typeface">serif</item>
</style>

Au lieu de themes.xml, comme indiqué dans le lien ci-dessus, j'ai mentionné la police par défaut à remplacer dans mon styles.xml dans la balise de thème d'application par défaut. Les polices par défaut pouvant être écrasées sont serif, sans, monospace et normal.

TypefaceUtil.Java

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    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) {
            Log.e("Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

Au départ, je ne savais pas que les polices à écraser étaient fixes et un ensemble de valeurs définies, mais cela m'a finalement aidé à comprendre comment Android traite les polices et les polices et leurs valeurs par défaut, ce qui est un point différent du cours.

1
Amruta-Pani

Définir une police personnalisée sur ProgressDialog/AlertDialog normal:

font=Typeface.createFromAsset(getAssets(),"DroidSans.ttf");

ProgressDialog dialog = ProgressDialog.show(this, "titleText", "messageText", true);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("message", "id", "Android"))).setTypeface(font);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("alertTitle", "id", "Android"))).setTypeface(font);
1
artProc

Travailler pour Xamarin.Android:

Classe:

public class FontsOverride
{
    public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
    {
        Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
        ReplaceFont(staticTypefaceFieldName, regular);
    }

    protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
    {
        try
        {
            Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
            staticField.Accessible = true;
            staticField.Set(null, newTypeface);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

Mise en œuvre de l'application:

namespace SomeAndroidApplication
{
    [Application]
    public class App : Application
    {
        public App()
        {

        }

        public App(IntPtr handle, JniHandleOwnership transfer)
            : base(handle, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
        }
    }
}

Style:

<style name="Theme.Storehouse" parent="Theme.Sherlock">
    <item name="Android:typeface">monospace</item>
</style>
0
Guy Micciche

Il peut être utile de savoir qu’à partir d’Android 8.0 (API niveau 26), vous pouvez utiliser une police personnalisée sous XML .

En termes simples, vous pouvez le faire de la manière suivante.

  1. Placez la police dans le dossier res/font.

  2. Soit l'utiliser dans l'attribut d'un widget 

<Button Android:fontFamily="@font/myfont"/>

ou le mettre dans res/values/styles.xml

<style name="MyButton" parent="Android:Widget.Button">
    <item name="Android:fontFamily">@font/myfont</item>
</style>

et l'utiliser comme un style

<Button style="@style/MyButton"/>
0
Vic

J'aime la suggestion de pospi. Pourquoi ne pas utiliser à fond la propriété "tag" d'une vue (que vous pouvez spécifier en XML - "Android: tag") pour spécifier tout style supplémentaire que vous ne pouvez pas utiliser en XML. J'aime JSON, je voudrais donc utiliser une chaîne JSON pour spécifier un ensemble clé/valeur. Cette classe fait le travail - appelez simplement Style.setContentView(this, [resource id]) dans votre activité.

public class Style {

  /**
   * Style a single view.
   */
  public static void apply(View v) {
    if (v.getTag() != null) {
      try {
        JSONObject json = new JSONObject((String)v.getTag());
        if (json.has("typeface") && v instanceof TextView) {
          ((TextView)v).setTypeface(Typeface.createFromAsset(v.getContext().getAssets(),
                                                             json.getString("typeface")));
        }
      }
      catch (JSONException e) {
        // Some views have a tag without it being explicitly set!
      }
    }
  }

  /**
   * Style the passed view hierarchy.
   */
  public static View applyTree(View v) {
    apply(v);
    if (v instanceof ViewGroup) {
      ViewGroup g = (ViewGroup)v;
      for (int i = 0; i < g.getChildCount(); i++) {
        applyTree(g.getChildAt(i));
      }
    }
    return v;
  }

  /**
   * Inflate, style, and set the content view for the passed activity.
   */
  public static void setContentView(Activity activity, int resource) {
    activity.setContentView(applyTree(activity.getLayoutInflater().inflate(resource, null)));
  }
}

De toute évidence, vous voudrez peut-être utiliser plus que la police de caractère pour rendre l'utilisation de JSON utile. 

Un avantage de la propriété 'tag' est que vous pouvez le définir sur un style de base que vous utilisez comme thème et le faire ainsi appliquer automatiquement à toutes vos vues. EDIT: Cela entraîne un crash lors de l'inflation sous Android 4.0.3. Vous pouvez toujours utiliser un style et l'appliquer individuellement à des vues de texte.

Une chose que vous verrez dans le code - certaines vues ont une balise sans que celle-ci soit explicitement définie - bizarrement, c'est la chaîne "οποκοπ" - qui est "coupé" en grec, selon Google Translate! Que se passe-t-il...?

0
Richard

La réponse de @ majinboo est révisée pour la gestion de la performance et de la mémoire. Plus d'une police liée à un besoin de l'activité Activity peut utiliser cette classe Font en donnant le constructeur lui-même comme paramètre.

@Override
public void onCreate(Bundle savedInstanceState)
{
    Font font = new Font(this);
}

La classe de polices révisée est la suivante:

public class Fonts
{
    private HashMap<AssetTypefaces, Typeface> hashMapFonts;

    private enum AssetTypefaces
    {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    public Fonts(Context context)
    {
        AssetManager mngr = context.getAssets();

        hashMapFonts = new HashMap<AssetTypefaces, Typeface>();
        hashMapFonts.put(AssetTypefaces.RobotoLight, Typeface.createFromAsset(mngr, "fonts/Roboto-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoThin, Typeface.createFromAsset(mngr, "fonts/Roboto-Thin.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedBold, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Bold.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedLight, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedRegular, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Regular.ttf"));
    }

    private Typeface getTypeface(String fontName)
    {
        try
        {
            AssetTypefaces typeface = AssetTypefaces.valueOf(fontName);
            return hashMapFonts.get(typeface);
        }
        catch (IllegalArgumentException e)
        {
            // e.printStackTrace();
            return Typeface.DEFAULT;
        }
    }

    public void setupLayoutTypefaces(View v)
    {
        try
        {
            if (v instanceof ViewGroup)
            {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++)
                {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            }
            else if (v instanceof TextView)
            {
                ((TextView) v).setTypeface(getTypeface(v.getTag().toString()));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            // ignore
        }
    }
}
0
Suphi ÇEVİKER

Je ne sais pas si cela modifie toute l'application, mais j'ai réussi à modifier certains composants qui ne pourraient pas autrement être modifiés en procédant ainsi:

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);
0
Richard

Il semble que l'utilisation de polices personnalisées ait été simplifiée avec Android O, vous pouvez utiliser essentiellement xml pour y parvenir. J'ai joint un lien vers la documentation officielle Android à titre de référence et j'espère que cela aidera les personnes qui ont encore besoin de cette solution. Utilisation de polices personnalisées sous Android

0
Mohale