web-dev-qa-db-fra.com

Accéder à une police sous le dossier assets à partir d'un fichier XML sous Android

J'essaie de faire un changement de police à l'échelle de l'application et de créer un fichier de style pour le faire. Dans ce fichier (ci-dessous), je souhaite simplement modifier la valeur de la police de caractères du style TextAppearance d’Android. 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NightRiderFont" parent="@Android:style/TextAppearance">
        <item name="Android:typeface"> /***help need here***/ </item>
    </style>
</resources>

Cependant, la police est dans "assets/fonts /". Comment puis-je accéder à cette police afin que je puisse utiliser ce style comme thème pour éviter de modifier manuellement toutes les TextViews. 

En résumé: Comment puis-je accéder à 'un fichier du dossier des actifs' en XML?

29
erkangur

Dans mes recherches, il n’existe aucun moyen d’ajouter une police externe au fichier XML. Seule la police 3 par défaut est disponible en xml

Mais vous pouvez utiliser en Java en utilisant ce code.

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/verdana.ttf");  
textfield.setTypeface(tf,Typeface.BOLD);

Mettre à jour:

Je trouve maintenant un moyen de le faire en créant une classe personnalisée qui étend le TextView et l’utilise dans le fichier XML. 

public class TextViewWithFont extends TextView {
    private int defaultDimension = 0;
    private int TYPE_BOLD = 1;
    private int TYPE_ITALIC = 2;
    private int FONT_ARIAL = 1;
    private int FONT_OPEN_SANS = 2;
    private int fontType;
    private int fontName;

    public TextViewWithFont(Context context) {
        super(context);
        init(null, 0);
    }
    public TextViewWithFont(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }
    public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }
    private void init(AttributeSet attrs, int defStyle) {
        // Load attributes
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.font, defStyle, 0);
        fontName = a.getInt(R.styleable.font_name, defaultDimension);
        fontType = a.getInt(R.styleable.font_type, defaultDimension);
        a.recycle();
        MyApplication application = (MyApplication ) getContext().getApplicationContext();
        if (fontName == FONT_ARIAL) {
            setFontType(application .getArialFont());
        } else if (fontName == FONT_OPEN_SANS) {
            setFontType(application .getOpenSans());
        }
    }
    private void setFontType(Typeface font) {
        if (fontType == TYPE_BOLD) {
            setTypeface(font, Typeface.BOLD);
        } else if (fontType == TYPE_ITALIC) {
            setTypeface(font, Typeface.ITALIC);
        } else {
            setTypeface(font);
        }
    }
}

et en xml

<com.example.customwidgets.TextViewWithFont
        font:name="Arial"
        font:type="bold"
        Android:layout_width="wrap_content"
        Android:text="Hello world "
        Android:padding="5dp"
        Android:layout_height="wrap_content"/>

n'oubliez pas d'ajouter le schéma à la racine de votre xml

xmlns:font="http://schemas.Android.com/apk/res-auto"

Et créez un fichier attrs.xml dans le répertoire values, qui contient nos attributs personnalisés:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="font">
        <attr name="type">
        <enum name="bold" value="1"/>
            <enum name="italic" value="2"/>
        </attr>
        <attr name="name">
            <enum name="Arial" value="1"/>
            <enum name="OpenSans" value="2"/>
        </attr>
    </declare-styleable>
</resources>

Mettre à jour:

Problème de performances détecté lorsque cette vue personnalisée est utilisée dans listview, c’est que la police Object crée chaque fois le fichier La vue est chargée. La solution que j'ai trouvée consiste à initialiser la police dans Application Classe et référence cet objet de police par

MyApplication application = (MyApplication) getContext().getApplicationContext();

La classe d'application ressemblera à ceci

public class MyApplication extends Application {

    private Typeface arialFont, openSans;

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

        arialFont = Typeface.createFromAsset(getAssets(), QRUtils.FONT_ARIAL);
        openSans = Typeface.createFromAsset(getAssets(), QRUtils.FONT_OPEN_SANS);
    }

    public Typeface getArialFont() {
        return arialFont;
    }

    public Typeface getOpenSans() {
        return openSans;
    }
}
72
droid kid

Edit 2:

Enfin, les polices sont supportées par xml (également compatible avec la bibliothèque de support): https://developer.Android.com/preview/features/fonts-in-xml.html


Modifier:

J'utilise maintenant la Calligraphy library. C'est le moyen le plus simple pour les polices personnalisées.

Que pouvez-vous faire:

  • Police personnalisée dans une TextView
  • Police personnalisée dans TextAppearance
  • Police personnalisée dans les styles
  • Police personnalisée dans les thèmes
  • FontSpannable pour appliquer la police uniquement à une partie du texte

J'ai trouvé un autre moyen de le faire.

Vous devez créer votre propre TextView en utilisant ce tutorial

Ce n'est pas si difficile et après cela, vous pouvez simplement utiliser cette TextView avec votre propre police.

Je ne sais pas si quelqu'un regarde encore cela, mais j'ai pensé que cela pourrait aider.

7
Kevin van Mierlo

Utilise cette fonction si vous utilisez une police unique.

public static void applyFont(final Context context, final View root, final String fontName) {
        try {
            if (root instanceof ViewGroup) {
                ViewGroup viewGroup = (ViewGroup) root;
                for (int i = 0; i < viewGroup.getChildCount(); i++)
                    applyFont(context, viewGroup.getChildAt(i), fontName);
            } else if (root instanceof TextView)
                ((TextView) root).setTypeface(Typeface.createFromAsset(context.getAssets(), fontName));
        } catch (Exception e) {
            Log.e("ProjectName", String.format("Error occured when trying to apply %s font for %s view", fontName, root));
            e.printStackTrace();
        }
    }
5
Ashwin S Ashok

Soorya a raison, mais si vous devez mettre la même police sur de nombreux textViews, je vous recommande de placer ce code dans une méthode statique qui renvoie le caractère recherché. Cela réduira les lignes dans votre code. Ou mieux encore, créez une classe qui étend Application et créez une méthode GET qui renvoie le type de caractère. Cette méthode sera accessible à partir de n'importe quelle activité de votre application (sans qu'il soit nécessaire d'utiliser des variables statiques ou des méthodes statiques).

2
gian1200

fount change est une fonctionnalité très basique d'Android qui est principalement nécessaire pour chaque application. Ainsi, chaque application ne souhaite changer qu'une seule fois dans une application, ce qui réduit notre temps de développement. Je vous suggère donc de voir ce lien FountChanger.class .

1
John smith

J'ai pris la réponse de droid kid et l'ai fait fonctionner avec N'IMPORTE QUELLE police, simplement en tapant le nom du fichier de police directement dans le XML:

layout.xml

<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:custom="http://schemas.Android.com/apk/res-auto" >

    <!-- where font file is at "assets/fonts/arial.ttf" -->
    <com.odbol.widgets.TextViewWithFont
        ...
        custom:fontFilePath="fonts/arial.ttf" />

</RelativeLayout>

Fonts.Java

public class Fonts {

    // use Weak so fonts are freed from memory when you stop using them
    private final static Map<String, Typeface> fonts = new WeakHashMap<>(5);

    /***
     * Returns a font at the given path within the assets directory.
     *
     * Caches fonts to save resources.
     *
     * @param context
     * @param fontPath Path to a font file relative to the assets directory, e.g. "fonts/Arial.ttf"
     * @return
     */
    public synchronized static Typeface getFont(Context context, String fontPath) {
        Typeface font = fonts.get(fontPath);

        if (font == null) {
            font = Typeface.createFromAsset(context.getAssets(), fontPath);
            fonts.put(fontPath, font);
        }

        return font;
    }
}

values ​​/ attrs.xml

<resources>

    <declare-styleable name="TextViewWithFont">
        <!-- a path to a font, relative to the assets directory -->
        <attr name="fontFilePath" format="string" />

        <attr name="type">
            <enum name="bold" value="1"/>
            <enum name="italic" value="2"/>
        </attr>
    </declare-styleable>
</resources>

TextViewWithFont.Java

public class TextViewWithFont extends TextView {
    private int defaultDimension = 0;
    private int TYPE_BOLD = 1;
    private int TYPE_ITALIC = 2;
    private int fontType;
    private int fontName;

    public TextViewWithFont(Context context) {
        super(context);
        init(null, 0);
    }
    public TextViewWithFont(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }
    public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }
    private void init(AttributeSet attrs, int defStyle) {
        // Load attributes
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.TextViewWithFont, defStyle, 0);
        String fontPath = a.getString(R.styleable.TextViewWithFont_fontFilePath);
        fontType = a.getInt(R.styleable.TextViewWithFont_type, defaultDimension);
        a.recycle();

        if (fontPath != null) {
            setFontType(Fonts.getFont(getContext(), fontPath));
        }
    }
    private void setFontType(Typeface font) {
        if (fontType == TYPE_BOLD) {
            setTypeface(font, Typeface.BOLD);
        } else if (fontType == TYPE_ITALIC) {
            setTypeface(font, Typeface.ITALIC);
        } else {
            setTypeface(font);
        }
    }
}
1
phreakhead

Vous venez de faire des appels publics et méthode attachée comme ça

public class TextViewFontType {

public Typeface typeface;

public void fontTextView(final TextView textView, final String fonttype) {
    typeface = Typeface.createFromAsset(textView.getContext().getAssets(), fonttype);
    textView.setTypeface(typeface);
}

avez-vous utilisé une méthode where avec TextView set font-family.

public class FontList {

    public static final String gothicbNormal="fonts/gothicb.ttf";
    public static final String gothicbBold="fonts/gothicb.ttf";
}

fait calss FontList après que vous ayez juste appelé des méthodes any avec where pass deux paramètres. 

1
MalhotraUrmil

Au lieu du dossier assets, vous pouvez placer le fichier .ttf dans le dossier des polices . Pour utiliser la prise en charge des polices dans la fonctionnalité XML sur les appareils exécutant Android 4.1 (API de niveau 16) ou supérieur, utilisez la bibliothèque de support 26 + . Right. cliquez sur le dossier res, nouveau -> Répertoire des ressources Android-> sélectionnez la police -> OK . placez votre fichier "myfont.ttf" dans le dossier de polices nouvellement créé.

Sur res/values ​​/ styles.xml Add,

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

Dans le fichier de mise en page, ajoutez Android: textAppearance = "@ style/customfontstyle",

<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:textAppearance="@style/customfontstyle"/>

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

0
Thomas V J

// accéder au fichier de police dans le code,

Typeface type = Typeface.createFromAsset(getResources().getAssets(),"fonts/arial.ttf");
textView.setTypeface(type);//assign typeface to textview

// dans le dossier assets -> polices (nom de répertoire) -> arial.ttf (nom du fichier de police)

0
vbijoor

espérons utiliser plein à vous: -

TextView text = (TextView) findViewById(R.id.custom_font);
Typeface font = Typeface.createFromAsset(getAssets(), "yourfont.ttf");
text.setTypeface(font);
0
duggu

Vous pouvez utiliser cette bibliothèque: https://github.com/chrisjenx/Calligraphy

Il vous suffit d’ajouter la police que vous souhaitez utiliser sur votre mise en page .

<TextView
 fontPath="fonts/verdana.ttf"
 Android:layout_width="wrap_content"
 Android:layout_height="wrap_content"/>