Android: vuoi impostare caratteri personalizzati per l'intera applicazione non runtime


100

È possibile impostare qualsiasi carattere personalizzato in ogni controllo dell'applicazione? E non necessariamente runtime? (cioè da xml se possibile o solo una volta per l'intera applicazione nel file JAVA)

Posso impostare il carattere per un controllo da questo codice.

public static void setFont(TextView textView) {
    Typeface tf = Typeface.createFromAsset(textView.getContext()
            .getAssets(), "fonts/BPreplay.otf");

    textView.setTypeface(tf);

}

E il problema con questo codice è che dovrebbe essere chiamato per ogni controllo. E voglio chiamare questo o qualsiasi metodo simile una volta o, se possibile, impostare la proprietà in xml. È possibile?


6
Potrebbe essere possibile scrivere un controllo personalizzato estendendo il TextView e l'impostazione del carattere nel costruttore potrebbe essere un'opzione, quindi puoi utilizzare questo controllo in tutta l'app al posto della tua textview. anche per risparmiare memoria è possibile impedire il caricamento di risorse utilizzando un tipo di carattere statico.
Varun

@ Varun: beh, questa idea può farmi risparmiare tempo, ma devo impostare tutti i controlli e scrivere controlli personalizzati per ciascuno sarà un modo più lungo rispetto all'impostazione di un runtime di font, cosa ne pensi? (Tuttavia +1 per la scrittura del controllo personalizzato)
Prasham

Potresti voler scrivere solo un controllo personalizzato che estende il textView e l'unica modifica sarà l'impostazione del carattere tipografico. Usando il controllo cusotm nei tuoi file di layout non devi farlo manualmente ogni volta per ogni visualizzazione di testo e puoi comunque essere certo che stai usando il carattere che desideri.
Varun

Che ne dici di scrivere un'abitudine VIEWinvece di scrivere a custom text viewe a custom button viewseparatamente? Il mio requisito è per ogni controllo e la visualizzazione del testo era solo un esempio. Scusa, mi sono dimenticato di menzionarlo .. :-(
Prasham

1
Dai un'occhiata a satckoverflow domanda stackoverflow.com/questions/2711858/... ti aiuta.
Ashwini

Risposte:


123

EDIT : Quindi è passato un po 'di tempo e vorrei aggiungere quello che penso sia il modo migliore per farlo, e tramite XML non meno!

Quindi, per prima cosa, vorrai creare una nuova classe che sovrascriva qualsiasi visualizzazione che desideri personalizzare. (ad esempio, vuoi un pulsante con un carattere tipografico personalizzato? Estendi Button). Facciamo un esempio:

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

Ora, se non ne hai uno, aggiungi un documento XML sotto res/values/attrs.xmle aggiungi:

<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>

Ok, quindi con quello fuori mano, torniamo al parseAttributes()metodo di prima:

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

Ora sei pronto. Puoi aggiungere più attributi per qualsiasi cosa (potresti aggiungerne un altro per typefaceStyle - grassetto, corsivo, ecc.) Ma ora vediamo come usarlo:

<?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>

La xmlns:customlinea può davvero essere qualsiasi cosa, ma la convenzione è quella mostrata sopra. Ciò che conta è che sia unico ed è per questo che viene utilizzato il nome del pacchetto. Ora usi solo il custom:prefisso per i tuoi attributi e il android:prefisso per gli attributi Android.

Un'ultima cosa: se si desidera utilizzare questo in uno stile ( res/values/styles.xml), è necessario non aggiungere la xmlns:customriga. Basta fare riferimento al nome dell'attributo senza prefisso:

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

                               (PREVIOUS ANSWER)

Utilizzo di un carattere tipografico personalizzato in Android

Questo dovrebbe aiutare. Fondamentalmente, non c'è modo di farlo in XML e, per quanto ne so, non c'è modo più semplice per farlo in codice. Puoi sempre avere un metodo setLayoutFont () che crea il carattere tipografico una volta, quindi esegue setTypeface () per ciascuno. Dovresti solo aggiornarlo ogni volta che aggiungi un nuovo elemento a un layout. Qualcosa come di seguito:

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 : Quindi sono appena riuscito a implementare qualcosa del genere da solo, e il modo in cui ho finito per farlo è stato creare una funzione come questa:

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

Quindi, usa questo metodo da onCreate () e passa tutti i TextView che desideri aggiornare:

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

EDIT 9/5/12:

Quindi, poiché questo continua a ricevere visualizzazioni e voti, vorrei aggiungere un metodo molto migliore e più completo:

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

Se gli passi la radice del tuo layout, controllerà ricorsivamente TextViewo vedrà Button(o qualsiasi altra cosa che aggiungi a quell'istruzione if) all'interno di quel layout e imposterà il carattere senza che tu debba specificarli per ID. Questo ovviamente presuppone che tu voglia impostare il carattere per ogni vista.


1
Non vedo alcuna differenza nel tuo codice e nel mio codice tranne che uso il metodo come metodo di fabbrica per l'intera applicazione e il tuo codice sembra essere scritto per un'attività. PS è davvero strano aggiungere un altro oggetto per un textView di sola lettura solo per cambiare il carattere. Fuori argomento: Android dovrebbe davvero introdurre un meccanismo per recuperare un carattere dalla cartella degli assest e da includere in R in modo che possa essere modificato in fase di progettazione)
Prasham

1
Immagino che realisticamente non ci sia alcuna differenza importante oltre a non creare il carattere tipografico più e più volte. L'idea di Varun di usare solo un carattere statico farebbe la stessa cosa.
Kevin Coppock

1
La riga finale del codice di esempio dovrebbe essere setLayoutFont (tf, tv1, tv2, tv3, tv4, tv5); piuttosto che setTypeface (tf, tv1, tv2, tv3, tv4, tv5) ;?
Kyle Clegg

1
Non dovresti recycleil TypedArray values?
CorayThan

1
Se si utilizza Gradle, lo spazio dei nomi personalizzato dovrebbe esserexmlns:custom="http://schemas.android.com/apk/res-auto"
Jabari

93

C'è un modo abbastanza semplice per farlo tramite XML. Hai solo bisogno di creare il tuo widget che estenda TextView.

Innanzitutto, crea un file in res / values ​​/ attrs.xml con il seguente contenuto:

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

Successivamente, crea il tuo widget personalizzato:

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

}

Come puoi vedere, il codice sopra leggerà un carattere all'interno della cartella assets /. Per questo esempio, presumo che sia presente un file denominato "custom.ttf" nella cartella degli asset. Infine, usa il widget negli XML:

<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" />

Nota: non sarai in grado di vedere il tuo carattere personalizzato nell'editor di layout di Eclipse. Questo è il motivo per cui ho messo l' isInEditMode()assegno. Ma se esegui la tua app, il carattere personalizzato funzionerà come un incantesimo.

Spero che sia d'aiuto!


Non l'ho provato, ma ho creato un controllo personalizzato estendendo la TextViewclasse; impostarlo typefacee usare il controllo personalizzato nel layout come facciamo normalmente e ha funzionato per me ... Era semplice, però, che quello sopra ...
Mahendra Liya

1
Ho fatto esattamente quello che hai detto. L'unica differenza è che ho reso questo componente riutilizzabile, perché la domanda chiede come farlo tramite XML. C'è davvero un modo per farlo tramite XML e questo è il modo per farlo :)
leocadiotine

Codice molto facile da integrare. Per me funziona. Grazie.
Durai

1
Questa dovrebbe essere la risposta accettata. Ben scritto. Grazie!
Reaz Murshed

1
Amesome, @DominikSuszczewicz! Puoi condividere il codice in modo che io possa aggiornare la risposta?
leocadiotina

15

Esempio di TextView con carattere roboto:

attr.xml

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

<declare-styleable name="RobotoTextView">
    <attr name="typeface"/>
</declare-styleable>

<attr name="typeface" format="enum">
    <enum name="roboto_thin" value="0"/>
    <enum name="roboto_thin_italic" value="1"/>
    <enum name="roboto_light" value="2"/>
    <enum name="roboto_light_italic" value="3"/>
    <enum name="roboto_regular" value="4"/>
    <enum name="roboto_italic" value="5"/>
    <enum name="roboto_medium" value="6"/>
    <enum name="roboto_medium_italic" value="7"/>
    <enum name="roboto_bold" value="8"/>
    <enum name="roboto_bold_italic" value="9"/>
    <enum name="roboto_black" value="10"/>
    <enum name="roboto_black_italic" value="11"/>
    <enum name="roboto_condensed" value="12"/>
    <enum name="roboto_condensed_italic" value="13"/>
    <enum name="roboto_condensed_bold" value="14"/>
    <enum name="roboto_condensed_bold_italic" value="15"/>
</attr>

</resources>

RobotoTextView.java:

public class RobotoTextView extends TextView {

/*
 * Permissible values ​​for the "typeface" attribute.
 */
private final static int ROBOTO_THIN = 0;
private final static int ROBOTO_THIN_ITALIC = 1;
private final static int ROBOTO_LIGHT = 2;
private final static int ROBOTO_LIGHT_ITALIC = 3;
private final static int ROBOTO_REGULAR = 4;
private final static int ROBOTO_ITALIC = 5;
private final static int ROBOTO_MEDIUM = 6;
private final static int ROBOTO_MEDIUM_ITALIC = 7;
private final static int ROBOTO_BOLD = 8;
private final static int ROBOTO_BOLD_ITALIC = 9;
private final static int ROBOTO_BLACK = 10;
private final static int ROBOTO_BLACK_ITALIC = 11;
private final static int ROBOTO_CONDENSED = 12;
private final static int ROBOTO_CONDENSED_ITALIC = 13;
private final static int ROBOTO_CONDENSED_BOLD = 14;
private final static int ROBOTO_CONDENSED_BOLD_ITALIC = 15;
/**
 * List of created typefaces for later reused.
 */
private final static SparseArray<Typeface> mTypefaces = new SparseArray<Typeface>(16);

/**
 * Simple constructor to use when creating a view from code.
 *
 * @param context The Context the view is running in, through which it can
 *                access the current theme, resources, etc.
 */
public RobotoTextView(Context context) {
    super(context);
}

/**
 * Constructor that is called when inflating a view from XML. This is called
 * when a view is being constructed from an XML file, supplying attributes
 * that were specified in the XML file. This version uses a default style of
 * 0, so the only attribute values applied are those in the Context's Theme
 * and the given AttributeSet.
 * <p/>
 * <p/>
 * The method onFinishInflate() will be called after all children have been
 * added.
 *
 * @param context The Context the view is running in, through which it can
 *                access the current theme, resources, etc.
 * @param attrs   The attributes of the XML tag that is inflating the view.
 * @see #RobotoTextView(Context, AttributeSet, int)
 */
public RobotoTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    parseAttributes(context, attrs);
}

/**
 * Perform inflation from XML and apply a class-specific base style. This
 * constructor of View allows subclasses to use their own base style when
 * they are inflating.
 *
 * @param context  The Context the view is running in, through which it can
 *                 access the current theme, resources, etc.
 * @param attrs    The attributes of the XML tag that is inflating the view.
 * @param defStyle The default style to apply to this view. If 0, no style
 *                 will be applied (beyond what is included in the theme). This may
 *                 either be an attribute resource, whose value will be retrieved
 *                 from the current theme, or an explicit style resource.
 * @see #RobotoTextView(Context, AttributeSet)
 */
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    parseAttributes(context, attrs);
}

/**
 * Parse the attributes.
 *
 * @param context The Context the view is running in, through which it can access the current theme, resources, etc.
 * @param attrs   The attributes of the XML tag that is inflating the view.
 */
private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);

    int typefaceValue = values.getInt(R.styleable.RobotoTextView_typeface, 0);
    values.recycle();

    setTypeface(obtaintTypeface(context, typefaceValue));
}

/**
 * Obtain typeface.
 *
 * @param context       The Context the view is running in, through which it can
 *                      access the current theme, resources, etc.
 * @param typefaceValue values ​​for the "typeface" attribute
 * @return Roboto {@link Typeface}
 * @throws IllegalArgumentException if unknown `typeface` attribute value.
 */
private Typeface obtaintTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
    Typeface typeface = mTypefaces.get(typefaceValue);
    if (typeface == null) {
        typeface = createTypeface(context, typefaceValue);
        mTypefaces.put(typefaceValue, typeface);
    }
    return typeface;
}

/**
 * Create typeface from assets.
 *
 * @param context       The Context the view is running in, through which it can
 *                      access the current theme, resources, etc.
 * @param typefaceValue values ​​for the "typeface" attribute
 * @return Roboto {@link Typeface}
 * @throws IllegalArgumentException if unknown `typeface` attribute value.
 */
private Typeface createTypeface(Context context, int typefaceValue) throws IllegalArgumentException {
    Typeface typeface;
    switch (typefaceValue) {
        case ROBOTO_THIN:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Thin.ttf");
            break;
        case ROBOTO_THIN_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-ThinItalic.ttf");
            break;
        case ROBOTO_LIGHT:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Light.ttf");
            break;
        case ROBOTO_LIGHT_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-LightItalic.ttf");
            break;
        case ROBOTO_REGULAR:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
            break;
        case ROBOTO_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
            break;
        case ROBOTO_MEDIUM:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
            break;
        case ROBOTO_MEDIUM_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-MediumItalic.ttf");
            break;
        case ROBOTO_BOLD:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
            break;
        case ROBOTO_BOLD_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldItalic.ttf");
            break;
        case ROBOTO_BLACK:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Black.ttf");
            break;
        case ROBOTO_BLACK_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BlackItalic.ttf");
            break;
        case ROBOTO_CONDENSED:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Condensed.ttf");
            break;
        case ROBOTO_CONDENSED_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-CondensedItalic.ttf");
            break;
        case ROBOTO_CONDENSED_BOLD:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensed.ttf");
            break;
        case ROBOTO_CONDENSED_BOLD_ITALIC:
            typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-BoldCondensedItalic.ttf");
            break;
        default:
            throw new IllegalArgumentException("Unknown `typeface` attribute value " + typefaceValue);
    }
    return typeface;
}

}

Esempio di utilizzo:

<your.package.widget.RobotoTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:typeface="roboto_thin"
                android:textSize="22sp"
                android:text="Roboto Thin"/>

Risorse: caratteri Roboto e Noto


c'è un modo per utilizzare questa soluzione senza però correggere gli id ​​dei caratteri nella classe java? magari leggere questi campi finali da enum attrs .. private final static int ROBOTO_THIN = 0; privato finale statico int ROBOTO_THIN_ITALIC = 1; privato finale statico int ROBOTO_LIGHT = 2; ...
Arthur Melo

3

È troppo tardi ma il mio aiuta l'altro
ho creato CustomTextView che ha un attributo chiamato typeFace e si occupa di problemi di perdita di memoria con il caricamento del carattere tipografico senza cache

Prima Fontsclasse che carica i caratteri dalle risorse solo per una volta

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

import java.util.Hashtable;

/**
 * Created by tonyhaddad on 7/19/15.
 */
public class Fonts {
    private Context context;

    public Fonts(Context context) {
        this.context = context;
    }
    private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
            4);
    public static Typeface getTypeFace(Context context, String fileName) {
        Typeface tempTypeface = sTypeFaces.get(fileName);

        if (tempTypeface == null) {
            String fontPath=null;
            if(fileName=="metabold")
                fontPath ="fonts/Meta-Bold.ttf";

            else if(fileName=="metanormal")
                fontPath="fonts/Meta-Normal.ttf";
            else if(fileName=="gsligh")
                fontPath="fonts/gesslight.ttf";
            else if(fileName=="bold")
                fontPath="fonts/Lato-Bold.ttf";
            else if(fileName=="rcr")
                fontPath="fonts/RobotoCondensed-Regular.ttf";

            else if(fileName=="mpr")
                fontPath="fonts/MyriadPro-Regular.otf";
            else if(fileName=="rr")
                fontPath="fonts/Roboto-Regular.ttf";

            tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
            sTypeFaces.put(fileName, tempTypeface);
        }

        return tempTypeface;
    }
}

quindi è necessario aggiungere un attributo personalizzato in attrs.xml aggiungere questo

<declare-styleable name="CustomFontTextView">
        <attr name="typeFace" format="string" />

    </declare-styleable>

quindi classe personalizzata

 package package_name;

/**
 * Created by tonyhaddad on 8/26/15.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

import package_name.R;

public class CustomFontTextView extends TextView {

    String typeFace;


    public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (isInEditMode()) {
            return;
        }
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomFontTextView,
                0, 0);
        try {
            typeFace = a.getString(0);
        } finally {
            a.recycle();
        }

        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }
        init();
    }

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (isInEditMode()) {
            return;
        }
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomFontTextView,
                0, 0);
        try {
            typeFace = a.getString(0);
        } finally {
            a.recycle();
        }

        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }

        init();
    }

    public CustomFontTextView(Context context) {
        super(context);



        if(typeFace!=null && !typeFace.equalsIgnoreCase(""))
        {
            Typeface tf = Fonts.getTypeFace(context, typeFace);
            setTypeface(tf);
        }
        init();
    }


    private void init() {

    }

    public String getTypeFace() {
        return typeFace;
    }

    public void setTypeFace(String typeFace) {
        this.typeFace = typeFace;
        invalidate();
        requestLayout();
    }
}

e infine aggiungi la visualizzazione del testo

  <package_name.CustomFontTextView
            xmlns:custom="http://schemas.android.com/apk/res-auto/package_name"
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="41dp"
            android:gravity="center_vertical"
            android:text="text"
            android:textColor="#000"
            android:textSize="23sp"
            custom:typeFace="metanormal"/>

e puoi cambiare il carattere progressivamente con il metodo setTypeFace
inoltre puoi spostare lo spazio dei nomi personalizzato nel layout genitore se vuoi uno da questa vista

Codifica felice :)


semplice risposta stratight.
eyadMhanna

2

Il metodo seguente, chiamato in onCreate () e passato al tuo ViewGroup più esterno, funzionerà per tutto tranne il testo che viene creato dinamicamente (cioè elenchi dinamici, avvisi, ecc.). Un modo semplice per ottenere il ViewGroup più esterno è usare getRootView su una qualsiasi delle tue viste.

public void onCreate(Bundle savedInstanceState){
    //onCreate code...
    EditText text = (EditText) findViewById(R.id.editText1);
    setTypeFaceForViewGroup((ViewGroup) text.getRootView());
}

private void setTypeFaceForViewGroup(ViewGroup vg){

    for (int i = 0; i < vg.getChildCount(); i++) {

            if (vg.getChildAt(i) instanceof ViewGroup)
                setTypeFaceForViewGroup((ViewGroup) vg.getChildAt(i));

            else if (vg.getChildAt(i) instanceof TextView)
                ((TextView) vg.getChildAt(i)).setTypeface(Typeface.createFromAsset(getAssets(), "fonts/Your_Font.ttf"));

    }

}

Questo dovrebbe funzionare anche per i contenuti dinamici, dovresti solo chiamarlo, passando quello che hai creato, subito dopo averlo creato (non l'ho testato, però).

Per risparmiare memoria, probabilmente vorrai rendere il carattere una variabile statica, piuttosto che crearne uno nuovo ogni volta che il ciclo viene eseguito come ho qui.


Non consiglio questa soluzione, perché stai creando una nuova istanza dello stesso carattere per ogni elemento a cui vuoi applicarlo. Ciò potrebbe causare problemi di memoria.
Flawyte

Questo è coperto nella mia nota alla fine.
Chris

2

Se stai cercando una soluzione programmatica più generale, ho creato una classe statica che può essere utilizzata per impostare il carattere tipografico di un'intera vista (interfaccia utente attività). Nota che sto lavorando con Mono (C #) ma puoi implementarlo facilmente usando Java.

È possibile passare a questa classe un layout o una visualizzazione specifica che si desidera personalizzare. Se vuoi essere super efficiente puoi implementarlo usando il 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");
            }
        }

    }

Nella tua attività dovrai creare un oggetto Typeface. Creo il mio in OnCreate () usando un file .ttf posto nella mia directory Resources / Assets /. Assicurati che il file sia contrassegnato come risorsa Android nelle sue proprietà.

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

2

Sfortunatamente, Android non fornisce il modo rapido, semplice e pulito che stai cercando per cambiare il carattere per l'intera app. Ma di recente ho esaminato la questione e ho creato alcuni strumenti che ti consentono di cambiare il carattere senza alcuna codifica (puoi farlo tutto tramite xml, stili e persino aspetti del testo). Si basano su soluzioni simili come quelle che vedi nelle altre risposte qui, ma consentono una flessibilità molto maggiore. Puoi leggere tutto su questo blog e vedere il progetto GitHub qui .

Ecco un esempio di come applicare questi strumenti. Metti tutti i tuoi file di font in formato assets/fonts/. Quindi, dichiara quei caratteri in un file xml (ad esempio res/xml/fonts.xml) e carica questo file all'inizio della tua app con TypefaceManager.initialize(this, R.xml.fonts);(ad esempio, in onCreate della tua classe Application). Il file xml ha questo aspetto:

<?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>

Ora puoi usare questi caratteri nel tuo stile o xml (a condizione che tu usi gli strumenti che ho menzionato sopra), usando l'elemento UI personalizzato com.innovattic.font.FontTextViewnel tuo layout xml. Di seguito puoi vedere come applicare un carattere a tutti i testi nell'intera app, semplicemente modificando 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="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>

Con l'accompagnamento 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.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>

Non dimenticare di applicare il tema nel tuo manifest Android.


2

Vorrei aggiungere una nota all'ottima soluzione di leocadiotine. È perfetto, ma quando si utilizza questa visualizzazione di testo personalizzata molte volte l'applicazione rallenta, poiché deve accedere alle risorse ogni volta che viene creata una visualizzazione di testo. Suggerisco di usare qualcosa come View Holder patternin Adapters, ho scritto un esempio:

public class Fonts {

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

    public static Typeface getTypeface(Context ctx, String fontName) {
        Typeface typeface = typefaces.get(fontName);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(ctx.getAssets(), fontName);
            typefaces.put(fontName, typeface);
        }
        return typeface;
    } 
}

In questo modo l'applicazione accede alle risorse solo una volta per risorsa e le conserva in memoria per ulteriori necessità.


0

Non so se cambia l'intera app, ma sono riuscito a cambiare alcuni componenti che altrimenti non potrebbero essere modificati in questo modo:

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);

@richard, voglio impostare il carattere personalizzato in base alle impostazioni locali, ad esempio, voglio impostare Arial TTF ogni volta che usiamo la lingua inglese e impostare il gotico TTF quando uso loacale coreano
Dwivedi Ji

0

Ho trovato informazioni dettagliate a questo link, link: https://github.com/jaydipumaretiya/CustomTypeface/

Ci sono molti modi per usare correttamente il carattere tipografico in Android, devi mettere il tuo file del carattere tipografico nella cartella delle risorse direttamente sotto il tuo principale e puoi usarlo in fase di esecuzione.

Un altro modo più semplice è utilizzare la libreria predefinita per impostare il carattere tipografico nel file xml. Ho preferito questa libreria di caratteri tipografici personalizzata per impostare il carattere tipografico su TextView, EditText, Button, CheckBox, RadioButton e AutoCompleteTextView e altri wedget in Android.


Il collegamento GitHub non funziona.
Thomas

0

Android 8.0 (livello API 26) introduce una nuova funzionalità, Caratteri in XML. Puoi creare un file di famiglia di caratteri e impostarlo in styles.xml.

Per aggiungere caratteri come risorse, eseguire i seguenti passaggi in Android Studio:

1.Fai clic con il pulsante destro del mouse sulla cartella res e vai su Nuovo> Directory delle risorse Android. Viene visualizzata la finestra Nuova directory delle risorse.

2.Nell'elenco Tipo di risorsa, selezionare il carattere, quindi fare clic su OK. Nota: il nome della directory delle risorse deve essere il carattere.

3.Aggiungere i file dei caratteri nella cartella dei caratteri.

Per creare una famiglia di caratteri, eseguire le seguenti operazioni:

1.Fai clic con il pulsante destro del mouse sulla cartella dei caratteri e vai a Nuovo> File di risorse dei caratteri. Viene visualizzata la finestra Nuovo file di risorse.

2. Immettere il nome del file, quindi fare clic su OK. Il nuovo XML della risorsa font si apre nell'editor.

3. Racchiudere ogni file di font, stile e attributo di peso nell'elemento. Il codice XML seguente illustra l'aggiunta di attributi relativi ai caratteri nell'XML delle risorse dei caratteri:

<?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/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

Aggiunta di caratteri allo stile

Apri styles.xml e imposta l'attributo fontFamily sul file del carattere a cui desideri accedere.

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

Fonte: caratteri in XML

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.