101 votes

Android : Souhaitez définir des polices personnalisées pour toute application pas DUREE

Est-il possible de mettre une police personnalisée à chaque contrôle de l’application ? Et pas nécessairement de runtime ? (c'est-à-dire à partir de xml si possible ou une seule fois pour toute application dans le fichier JAVA)

Je peux définir la police pour un contrôle à partir de ce code.

Et le problème avec ce code est qu'elle doit être appelée pour chaque contrôle. Et je veux appeler cela ou n’importe quelle méthode similaire une fois, ou si possible définie la propriété en xml. Est-ce possible ?

123voto

kcoppock Points 57219

EDIT: en fait ça fait un moment, et je tiens à ajouter que je pense est la meilleure façon pour ce faire, et grâce à XML pas moins!

Alors d'abord, vous allez avoir à faire une nouvelle classe qui remplace ce que la Vue que vous souhaitez personnaliser. (par exemple, veulent un Bouton avec une mesure de police? Étendre Button). Nous allons faire un exemple:

public class CustomButton extends Button {
    private final static int ROBOTO = 0;
    private final static int ROBOTO_CONDENSED = 1;

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

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context, attrs); //I'll explain this method later
    }

    public CustomButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        parseAttributes(context, attrs);
    }
}

Maintenant, si vous n'en avez pas, ajoutez un document XML en vertu de l' res/values/attrs.xml, et ajoutez:

<resources>
    <!-- Define the values for the attribute -->
    <attr name="typeface" format="enum">
        <enum name="roboto" value="0"/>
        <enum name="robotoCondensed" value="1"/>
    </attr>

    <!-- Tell Android that the class "CustomButton" can be styled, 
         and which attributes it supports -->
    <declare-styleable name="CustomButton">
        <attr name="typeface"/>
    </declare-styleable>
</resources>

D'accord, donc, avec cela, revenons à l' parseAttributes() méthode de plus en plus tôt:

private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);

    //The value 0 is a default, but shouldn't ever be used since the attr is an enum
    int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);

    switch(typeface) {
        case ROBOTO: default:
            //You can instantiate your typeface anywhere, I would suggest as a 
            //singleton somewhere to avoid unnecessary copies
            setTypeface(roboto); 
            break;
        case ROBOTO_CONDENSED:
            setTypeface(robotoCondensed);
            break;
    }

    values.recycle();
}

Maintenant vous êtes tous ensemble. Vous pouvez ajouter des attributs supplémentaires pour sujet de n'importe quoi (vous pouvez en ajouter un autre pour typefaceStyle -- gras, italique, etc.) mais maintenant, nous allons voir comment l'utiliser:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.yourpackage.name.CustomButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me!"
        custom:typeface="roboto" />

</LinearLayout>

L' xmlns:custom ligne peut vraiment être n'importe quoi, mais la convention est ce qui est indiqué ci-dessus. Ce qui importe, c'est qu'il est unique, et c'est pourquoi le nom du package est utilisé. Maintenant, il vous suffit d'utiliser l' custom: préfixe pour vos attributs, et l' android: préfixe pour android attributs.

Une dernière chose: si vous voulez l'utiliser dans un style (res/values/styles.xml), vous ne devez pas ajouter de l' xmlns:custom ligne de. Juste référence au nom de l'attribut avec aucun préfixe:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>

                               (PREVIOUS ANSWER)

En utilisant une mesure de police dans Android

Cela devrait aider. Fondamentalement, il n'y a aucun moyen de le faire en XML, et aussi loin que je peux dire, pas de moyen plus facile de le faire dans le code. Vous pourriez toujours avoir une setLayoutFont() méthode qui crée la police une fois, puis exécute setTypeface() pour chaque. Vous avez juste à le mettre à jour chaque fois que vous ajoutez un nouvel élément à une mise en page. Quelque chose comme ci-dessous:

public void setLayoutFont() {
    Typeface tf = Typeface.createFromAsset(
        getBaseContext().getAssets(), "fonts/BPreplay.otf");
    TextView tv1 = (TextView)findViewById(R.id.tv1);
    tv1.setTypeface(tf);

    TextView tv2 = (TextView)findViewById(R.id.tv2);
    tv2.setTypeface(tf);

    TextView tv3 = (TextView)findViewById(R.id.tv3);
    tv3.setTypeface(tf);
}

EDIT: je viens de recevoir autour à la mise en œuvre de quelque chose comme cela moi-même, et comment j'ai fini par faire, c'était faire une fonction comme ceci:

public static void setLayoutFont(Typeface tf, TextView...params) {
    for (TextView tv : params) {
        tv.setTypeface(tf);
    }
}

Ensuite, il suffit d'utiliser cette méthode onCreate(), et passer tous les TextViews vous souhaitez mettre à jour:

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
//find views by id...
setLayoutFont(tf, tv1, tv2, tv3, tv4, tv5);

EDIT 9/5/12:

Donc, puisque c'est toujours des points de vue et de voix, je voudrais ajouter une bien meilleure et plus complète de la méthode:

Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/BPreplay.otf");
ViewGroup root = (ViewGroup)findViewById(R.id.myrootlayout);
setFont(root, mFont);

/*
 * Sets the font on all TextViews in the ViewGroup. Searches
 * recursively for all inner ViewGroups as well. Just add a
 * check for any other views you want to set as well (EditText,
 * etc.)
 */
public void setFont(ViewGroup group, Typeface font) {
    int count = group.getChildCount();
    View v;
    for(int i = 0; i < count; i++) {
        v = group.getChildAt(i);
        if(v instanceof TextView || v instanceof Button /*etc.*/)
            ((TextView)v).setTypeface(font);
        else if(v instanceof ViewGroup)
            setFont((ViewGroup)v, font);
    }
}

Si vous passez à la racine de votre mise en page, il va vérifier de manière récursive pour TextView ou Button vues (ou tout autres vous ajoutez à cela que si l'instruction) à l'intérieur de cette disposition, et de définir la police sans que vous ayez à préciser par ID. C'est bien sûr en supposant que vous souhaitez définir la police de caractères à chaque vue.

93voto

leocadiotine Points 1386

Il est assez facile de le faire via XML. Il vous suffit de créer votre propre widget qui s'étend TextView.

Tout d'abord, créez un fichier dans res/values/attrs.xml avec le contenu suivant:

<resources>
    <declare-styleable name="TypefacedTextView">
        <attr name="typeface" format="string" />
    </declare-styleable>
</resources>

Après cela, créez votre widget personnalisé:

package your.package.widget;

public class TypefacedTextView extends TextView {

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

        //Typeface.createFromAsset doesn't work in the layout editor. Skipping...
        if (isInEditMode()) {
            return;
        }

        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.TypefacedTextView);
        String fontName = styledAttrs.getString(R.styleable.TypefacedTextView_typeface);
        styledAttrs.recycle();

        if (fontName != null) {
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), fontName);
            setTypeface(typeface);
        }
    }

}

Comme vous pouvez le voir, le code ci-dessus va lire une police à l'intérieur du dossier assets/. Pour cet exemple, je suppose qu'il y a un fichier appelé "personnalisé.ttf" dans le dossier assets. Enfin, utiliser le widget dans la XMLs:

<your.package.widget.TypefacedTextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:your_namespace="http://schemas.android.com/apk/res/your.package"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Custom fonts in XML are easy"
    android:textColor="#FFF"
    android:textSize="14dip"
    your_namespace:typeface="custom.ttf" />

Remarque: vous ne serez pas en mesure de voir vos polices personnalisées dans Eclipse en page de l'éditeur. C'est pourquoi j'ai mis la isInEditMode() vérifier. Mais si vous exécutez votre application, la police personnalisée fonctionne comme un charme.

Espérons que cela aide!

15voto

e.shishkin Points 419

Exemple de TextView avec roboto fonte :

attr.Xml

RobotoTextView.java :

Exemple d’utilisation :

2voto

JCKortlang Points 52

Si vous êtes à la recherche d'un cadre plus général programatic solution, j'ai créé une classe statique qui peut être utilisée pour définir le Caractère d'une vue d'ensemble (l'Activité de l'INTERFACE utilisateur). Notez que je suis en train de travailler avec Mono (C#) mais vous pouvez mettre en place facilement à l'aide de Java.

Vous pouvez passer cette classe une mise en page ou d'un point de vue spécifique que vous souhaitez personnaliser. Si vous voulez être super efficace vous pourriez mettre en œuvre en utilisant le pattern Singleton.

public static class AndroidTypefaceUtility 
{
    static AndroidTypefaceUtility()
    {
    }
    //Refer to the code block beneath this one, to see how to create a typeface.
    public static void SetTypefaceOfView(View view, Typeface customTypeface)
    {
    if (customTypeface != null && view != null)
    {
            try
            {
                if (view is TextView)
                    (view as TextView).Typeface = customTypeface;
                else if (view is Button)
                    (view as Button).Typeface = customTypeface;
                else if (view is EditText)
                    (view as EditText).Typeface = customTypeface;
                else if (view is ViewGroup)
                    SetTypefaceOfViewGroup((view as ViewGroup), customTypeface);
                else
                    Console.Error.WriteLine("AndroidTypefaceUtility: {0} is type of {1} and does not have a typeface property", view.Id, typeof(View));
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("AndroidTypefaceUtility threw:\n{0}\n{1}", ex.GetType(), ex.StackTrace);
                    throw ex;
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / view parameter should not be null");
            }
        }

        public static void SetTypefaceOfViewGroup(ViewGroup layout, Typeface customTypeface)
        {
            if (customTypeface != null && layout != null)
            {
                for (int i = 0; i < layout.ChildCount; i++)
                {
                    SetTypefaceOfView(layout.GetChildAt(i), customTypeface);
                }
            }
            else
            {
                Console.Error.WriteLine("AndroidTypefaceUtility: customTypeface / layout parameter should not be null");
            }
        }

    }

Dans votre activité, vous aurez besoin de créer une Police de caractères de l'objet. J'ai créer le mien dans le OnCreate() à l'aide d'un .ttf fichier placé dans mes Ressources/Actifs/ répertoire. Assurez-vous que le fichier est marqué comme étant un Android Atout dans ses "propriétés".

protected override void OnCreate(Bundle bundle)
{               
    ...
    LinearLayout rootLayout = (LinearLayout)FindViewById<LinearLayout>(Resource.Id.signInView_LinearLayout);
    Typeface allerTypeface = Typeface.CreateFromAsset(base.Assets,"Aller_Rg.ttf");
    AndroidTypefaceUtility.SetTypefaceOfViewGroup(rootLayout, allerTypeface);
}

2voto

Jelle Fresen Points 567

Malheureusement, Android ne fournit pas rapide, facile et propre vous cherchez à changer la police de caractères pour l'ensemble de votre application. Mais récemment, j'ai examiné cette question et a créé des outils qui vous permettent de modifier la police de caractères sans codage (vous pouvez le faire via un fichier xml, de styles et de texte, même les apparences). Ils sont basés sur des solutions similaires comme vous le voyez dans les autres réponses ici, mais de permettre à beaucoup plus de flexibilité. Vous pouvez lire tout ça sur ce blog, et vous pouvez télécharger le code ici.

Voici un exemple de la façon d'appliquer ces outils. Mettez tous vos fichiers de police en assets/fonts/. Ensuite, déclarer ces polices de caractères dans un fichier xml (par exemple, res/xml/fonts.xml) et de charger ce fichier au début de votre application avec des TypefaceManager.initialize(this, R.xml.fonts); (par exemple, dans le onCreate de votre classe d'Application). Le fichier xml ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?>
<familyset>

    <!-- Some Font. Can be referenced with 'someFont' or 'aspergit' -->
    <family>
        <nameset>
            <name>aspergit</name>
            <name>someFont</name>
        </nameset>
        <fileset>
            <file>Aspergit.ttf</file>
            <file>Aspergit Bold.ttf</file>
            <file>Aspergit Italic.ttf</file>
            <file>Aspergit Bold Italic.ttf</file>
        </fileset>
    </family>

    <!-- Another Font. Can be referenced with 'anotherFont' or 'bodoni' -->
    <family>
        <nameset>
            <name>bodoni</name>
            <name>anotherFont</name>
        </nameset>
        <fileset>
            <file>BodoniFLF-Roman.ttf</file>
            <file>BodoniFLF-Bold.ttf</file>
        </fileset>
    </family>

</familyset>

Maintenant, vous pouvez utiliser ces polices dans votre style ou xml (à condition que vous utilisez les outils que j'ai mentionnés ci-dessus), en utilisant l'élément d'INTERFACE personnalisé com.innovattic.view.FontTextView dans votre xml de mise en page. Ci-dessous vous pouvez voir comment vous pouvez appliquer une police à tous les textes de l'ensemble de votre application, juste en éditant res/values/styles.xml:

<?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="font">someFont</item>
        <item name="android:textStyle">bold|italic</item>
    </style>

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

</resources>

Avec l'accompagnement d' res/layout/layout.xml:

<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.view.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.view.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:font="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.view.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>

Ne pas oublier d'appliquer le thème dans votre manifeste Android.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X