Come modificare il carattere su TextView?


Risposte:


342

Innanzitutto, l'impostazione predefinita non è Arial. L'impostazione predefinita è Droid Sans.

In secondo luogo, per passare a un diverso font incorporato, utilizzare android:typefacenel layout XML o setTypeface()in Java.

Terzo, non esiste alcun font Helvetica in Android. Le opzioni integrate sono Droid Sans ( sans), Droid Sans Mono ( monospace) e Droid Serif ( serif). Sebbene sia possibile raggruppare i propri caratteri con l'applicazione e utilizzarli tramite setTypeface(), tenere presente che i file dei caratteri sono grandi e, in alcuni casi, richiedono accordi di licenza (ad esempio, Helvetica, un carattere Linotype ).

MODIFICARE

Il linguaggio di progettazione Android si basa su strumenti tipografici tradizionali come scala, spazio, ritmo e allineamento con una griglia sottostante. La corretta implementazione di questi strumenti è essenziale per aiutare gli utenti a comprendere rapidamente una schermata di informazioni. Per supportare tale uso della tipografia, Ice Cream Sandwich ha introdotto una nuova famiglia di tipi chiamata Roboto, creata appositamente per i requisiti dell'interfaccia utente e degli schermi ad alta risoluzione.

L'attuale framework TextView offre Roboto in pesi sottili, leggeri, regolari e audaci, insieme a uno stile corsivo per ogni peso. La struttura offre anche la variante Roboto Condensed in pesi regolari e audaci, insieme a uno stile corsivo per ogni peso.

Dopo ICS, Android include lo stile dei caratteri Roboto, Leggi di più Roboto

MODIFICA 2

Con l'avvento di Support Library 26, Android ora supporta i caratteri personalizzati per impostazione predefinita. È possibile inserire nuovi caratteri in res / fonts che possono essere impostati su TextViews singolarmente in XML o a livello di programmazione. Il carattere predefinito per l'intera applicazione può anche essere modificato definendolo styles.xml La documentazione per sviluppatori Android ha una guida chiara su questo qui


6
Non c'è modo di impostare i caratteri in XML? Perché?
Jonny

5
@Jonny In realtà puoi. Stai creando una classe che estende TextView e chiama setTypeface dal costruttore.
Mark Phillip

come farlo nel layout XML?
M. Usman Khan,

2
@usman: Avresti bisogno di una libreria di terze parti, come Calligrafia: github.com/chrisjenx/Calligraphy
CommonsWare

L'impostazione del carattere tipografico utilizzando il codice Java è difficile a causa di più righe, ho creato una libreria per impostare caratteri personalizzati. È possibile trovare un utilizzo libreria in questa risposta stackoverflow.com/a/42001474/4446392
Chathura Jayanath

254

Per prima cosa scarica il .ttffile del carattere che ti serve ( arial.ttf). Mettilo nella assets cartella. (All'interno della cartella delle risorse crea una nuova cartella denominata font e inseriscila al suo interno.) Usa il seguente codice per applicare il font al tuo TextView:

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);

Caro Mayur, qualche consiglio su dove ottenere questi file .ttf?
solitario

3
Caro @lonelearner puoi scaricare file di caratteri gratuiti (.ttf) in 1001freefonts.com o semplicemente google "Caratteri gratuiti"
ymerdrengene,

10
Per coloro che utilizzano Android Studio e non riescono a trovare una cartella "risorse", consulta questa domanda . Risposta breve: src/main/assets/fonts/.
adamdport,

51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);

33

Potresti voler creare una classe statica che conterrà tutti i caratteri. In questo modo, non creerai il carattere più volte che potrebbe avere un impatto negativo sulle prestazioni . Assicurati solo di creare una sottocartella denominata " caratteri " nella cartella " risorse ".

Fai qualcosa come:

public class CustomFontsLoader {

public static final int FONT_NAME_1 =   0;
public static final int FONT_NAME_2 =   1;
public static final int FONT_NAME_3 =   2;

private static final int NUM_OF_CUSTOM_FONTS = 3;

private static boolean fontsLoaded = false;

private static Typeface[] fonts = new Typeface[3];

private static String[] fontPath = {
    "fonts/FONT_NAME_1.ttf",
    "fonts/FONT_NAME_2.ttf",
    "fonts/FONT_NAME_3.ttf"
};


/**
 * Returns a loaded custom font based on it's identifier. 
 * 
 * @param context - the current context
 * @param fontIdentifier = the identifier of the requested font
 * 
 * @return Typeface object of the requested font.
 */
public static Typeface getTypeface(Context context, int fontIdentifier) {
    if (!fontsLoaded) {
        loadFonts(context);
    }
    return fonts[fontIdentifier];
}


private static void loadFonts(Context context) {
    for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
        fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
    }
    fontsLoaded = true;

}
}

In questo modo, puoi ottenere il carattere da qualsiasi parte dell'applicazione.


1
Amico fantastico! Questa è la bellezza di OOP. Ottimo lavoro! :)
Joshua Michael Wagoner,

Come uso questa classe?
Jack,

Devi inserire questo codice nel tuo progetto, adattarlo ai tuoi caratteri e quindi utilizzare il metodo statico getTypeface (..) da qualsiasi punto della tua app.
Daniel L.

Ho usato una soluzione simile, ma ho aggiunto la memorizzazione nella cache per migliorare le prestazioni .... in ogni caso, hai riscontrato una situazione in cui il carattere funziona su alcuni telefoni e non su altri?
RJFares

20

Le migliori pratiche di sempre

TextViewPlus.java:

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

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

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface typeface = null;
        try {
            typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
        } catch (Exception e) {
            Log.e(TAG, "Unable to load typeface: "+e.getMessage());
            return false;
        }

        setTypeface(typeface);
        return true;
    }
}

attrs.xml: (dove posizionare res / valori )

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

Come usare:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.mypackage.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="my_font_name_regular.otf">
    </com.mypackage.TextViewPlus>
</LinearLayout>

Spero che questo ti possa aiutare.


1
Perché la sottoclasse di TextView è la migliore pratica?
Rabbino

@Stealth Rabbi, qui possiamo trasmettere caratteri personalizzati solo con xml, non è necessario scrivere un codice java speciale per ogni visualizzazione di testo.
Hiren Patel,

C'è una biblioteca per quello. Aggiungi semplicemente il tuo carattere nella cartella delle risorse e dichiaralo in XML. github.com/febaisi/CustomTextView
febaisi

La tua libreria sembra a posto, ma l'unico problema è che è per Android 21+
loloof64

@febaisi come ho visto nel tuo esempio lib raw.githubusercontent.com/febaisi/CustomTextView/master/wiki/…
Mr.Q

17

Le risposte sopra sono corrette. Assicurati solo di creare una sottocartella denominata "caratteri" nella cartella "risorse" se stai usando quel pezzo di codice.


1
Il tuo commento è ridondante. La spiegazione sopra dice esattamente quello che hai detto, e altro ancora ...
Joshua Michael Wagoner,

14

Un altro modo per consolidare la creazione di caratteri ...

public class Font {
  public static final Font  PROXIMA_NOVA    = new Font("ProximaNovaRegular.otf");
  public static final Font  FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
  private final String      assetName;
  private volatile Typeface typeface;

  private Font(String assetName) {
    this.assetName = assetName;
  }

  public void apply(Context context, TextView textView) {
    if (typeface == null) {
      synchronized (this) {
        if (typeface == null) {
          typeface = Typeface.createFromAsset(context.getAssets(), assetName);
        }
      }
    }
    textView.setTypeface(typeface);
  }
}

E poi da usare nella tua attività ...

myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);

Intendiamoci, questo idioma di blocco ricontrollato con il campo volatile funziona correttamente solo con il modello di memoria utilizzato in Java 1.5+.


Perché questa risposta ha solo 1 voto e quella sopra ha 15? Cosa rende l'altro migliore? Mi sembra che questo sia il più semplice usando il principio singleton ...?
Koen Demonie,

Ho appena visto che hai il tuo costruttore pubblico, lo renderei privato dal momento che non hai bisogno di alcun accesso ad esso. Stai comunque usando i tuoi caratteri interni ...
Koen Demonie

Assolutamente dovrebbe essere un costruttore privato. Ben individuato :) Modifica!
Chris Aitchison,

12

È consigliabile utilizzare la libreria di supporto Android versione 26.0.0 o successiva.

PASSAGGIO 1: aggiungi il file del font

  1. Nella cartella res creare un nuovo dizionario delle risorse dei caratteri
  2. Aggiungi file di font ( .ttf , .orf )

Ad esempio, quando il file dei caratteri sarà helvetica_neue.ttf che genererà R.font.helvetica_neue

PASSAGGIO 2: creazione della famiglia di caratteri

  1. Nella cartella dei caratteri aggiungi un nuovo file di risorse
  2. Racchiudere ciascun file di font, stile e attributo weight nell'elemento.

Per esempio:

<?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/helvetica_neue" />
</font-family>

PASSAGGIO 3: utilizzalo

Nei layout XML:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/my_font"/>

O aggiungi caratteri allo stile:

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

Per ulteriori esempi puoi seguire la documentazione:

Lavorare con i caratteri


7

È un po 'vecchio, ma ho migliorato un po' la classe CustomFontLoader e volevo condividerla in modo che possa essere utile. Basta creare una nuova classe con questo codice.

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

public enum FontLoader {

ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");   


private final String name;
private Typeface typeFace;


private FontLoader(final String name) {
    this.name = name;

    typeFace=null;  
}

public static Typeface getTypeFace(Context context,String name){
    try {
        FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
        if(item.typeFace==null){                
            item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");                 
        }           
        return item.typeFace;
    } catch (Exception e) {         
        return null;
    }                   
}
public static Typeface getTypeFace(Context context,int id){
    FontLoader myArray[]= FontLoader.values();
    if(!(id<myArray.length)){           
        return null;
    } 
    try {
        if(myArray[id].typeFace==null){     
            myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");                       
        }       
        return myArray[id].typeFace;    
    }catch (Exception e) {          
        return null;
    }   

}

public static Typeface getTypeFaceByName(Context context,String name){      
    for(FontLoader item: FontLoader.values()){              
        if(name.equalsIgnoreCase(item.name)){
            if(item.typeFace==null){
                try{
                    item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
                }catch (Exception e) {          
                    return null;
                }   
            }
            return item.typeFace;
        }               
    }
    return null;
}   

public static void loadAllFonts(Context context){       
    for(FontLoader item: FontLoader.values()){              
        if(item.typeFace==null){
            try{
                item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
            }catch (Exception e) {
                item.typeFace=null;
            }   
        }                
    }       
}   
}

Quindi usa questo codice sulla tua visualizzazione di testo:

 Typeface typeFace=FontLoader.getTypeFace(context,"arial");  
 if(typeFace!=null) myTextView.setTypeface(typeFace);

5

Finalmente ho ottenuto una soluzione molto semplice a questo.

  1. utilizzare queste librerie di supporto in gradi a livello di app ,

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. quindi creare una directory denominata "font" all'interno della cartella res

  3. metti i file di font (ttf) in quella directory di font, tieni a mente le convenzioni di denominazione [egname non deve contenere caratteri speciali, maiuscoli e spazi o tab]
  4. Successivamente, fai riferimento a quel carattere da xml in questo modo

            <Button
            android:id="@+id/btn_choose_employee"
            android:layout_width="140dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:background="@drawable/rounded_red_btn"
            android:onClick="btnEmployeeClickedAction"
            android:text="@string/searching_jobs"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:fontFamily="@font/times_new_roman_test"
            />

In questo esempio, times_new_roman_test è un file ttf di font da quella directory di font


4
import java.lang.ref.WeakReference;
import java.util.HashMap;

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

public class FontsManager {

    private static FontsManager instance;

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

    private static Context context;

    private FontsManager(final Context ctx) {
        if (context == null) {
            context = ctx;
        }
    }

    public static FontsManager getInstance(final Context appContext) {
        if (instance == null) {
            instance = new FontsManager(appContext);
        }
        return instance;
    }

    public static FontsManager getInstance() {
        if (instance == null) {
            throw new RuntimeException(
                    "Call getInstance(Context context) at least once to init the singleton properly");
        }
        return instance;
    }

    public Typeface getFont(final String assetName) {
        final WeakReference<Typeface> tfReference = typefaces.get(assetName);
        if (tfReference == null || tfReference.get() == null) {
            final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
                    assetName);
            typefaces.put(assetName, new WeakReference<Typeface>(tf));
            return tf;
        }
        return tfReference.get();
    }

}

In questo modo, puoi creare una vista che eredita da TextView e chiama setTypeface sul suo costruttore.


1
Ciao, perché stai usando WeakReference per contenere l'oggetto TypeFace?
Pigro,

3

Quando il font è memorizzato all'interno, res/asset/fonts/Helvetica.ttfutilizzare quanto segue:

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf"); 
txt.setTypeface(tf);

Oppure, se il tuo file di caratteri è archiviato all'interno, res/font/helvetica.ttfutilizza quanto segue:

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);

2
Grazie, stavo cercando la parte in cui l'hai trovata nella cartella res!
Mikkel Larsen,

2

ottenere il carattere dall'asset e impostarlo su tutti i bambini

public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
         }
        } else if (v instanceof TextView ) {
            ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
        }
    } catch (Exception e) {
 }
 } 

2
  1. aggiungi classe FontTextView.java:


public class FontTextView extends TextView {
    String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};

    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (!isInEditMode()) {
            init(attrs);
        }

    }

    public FontTextView(Context context) {
        super(context);
        if (!isInEditMode()) {
            init(null);
        }
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
            if (a.getString(R.styleable.FontTextView_font_type) != null) {
                String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];

                if (fontName != null) {
                    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
                    setTypeface(myTypeface);
                }
                a.recycle();
            }
        }
    }
}


  1. aggiungi al font della libreria delle risorse
    inserisci qui la descrizione dell'immagine


  1. aggiungi a attrs.xml, I numeri devono essere nell'ordine nella classe dell'array.

    <declare-styleable name="FontTextView">
    <attr name="font_type" format="enum">
        <enum name="HelveticaNeue" value="0"/>
        <enum name="HelveticaNeueLight" value="1"/>
        <enum name="motschcc" value="2"/>
        <enum name="symbol" value="3"/>
    </attr>


  1. Seleziona un carattere dall'elenco
    inserisci qui la descrizione dell'immagine

Devi creare un'istanza di questa classe in MainActivity? Perché non sta cambiando nulla per me.
Tobias Mayr,

1

Android utilizza il carattere Roboto, che è davvero un bell'aspetto, con diversi pesi (normale, leggero, sottile, condensato) che si adattano perfettamente agli schermi ad alta densità.

Controlla sotto il link per controllare i caratteri roboto:

Come usare Roboto nel layout xml

Torna alla tua domanda, se vuoi cambiare il carattere per tutto il TextView / Button nella tua app , prova ad aggiungere il codice seguente nel tuo styles.xml per usare il carattere Roboto-light :

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ......
    <item name="android:buttonStyle">@style/MyButton</item>
    <item name="android:textViewStyle">@style/MyTextView</item>
</style>

<style name="MyButton" parent="@style/Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

E non dimenticare di usare "AppTheme" nel tuo AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ......
</application>

0

Forse qualcosa di un po 'più semplice:

public class Fonts {
  public static HashSet<String,Typeface> fonts = new HashSet<>();

  public static Typeface get(Context context, String file) {
    if (! fonts.contains(file)) {
      synchronized (this) {
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
        fonts.put(name, typeface);
      }
    }
    return fonts.get(file);
  }
}

// Usage
Typeface myFont = Fonts.get("arial.ttf");

(Nota che questo codice non è testato, ma in generale questo approccio dovrebbe funzionare bene.)

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.