Wie ändere ich die Schriftart in der Textansicht?

Antworten:

342

Erstens ist die Standardeinstellung nicht Arial. Der Standardwert ist Droid Sans.

Zweitens, um zu einer anderen integrierten Schriftart zu wechseln, verwenden Sie android:typefacein Layout-XML oder setTypeface()in Java.

Drittens gibt es in Android keine Helvetica-Schriftart. Die integrierten Optionen sind Droid Sans ( sans), Droid Sans Mono ( monospace) und Droid Serif ( serif). Während Sie Ihre eigenen Schriftarten mit Ihrer Anwendung bündeln und über verwenden können setTypeface(), sollten Sie berücksichtigen, dass die Schriftdateien groß sind und in einigen Fällen Lizenzvereinbarungen erfordern (z. B. Helvetica, eine Linotype-Schriftart ).

BEARBEITEN

Die Android-Designsprache basiert auf traditionellen typografischen Tools wie Skalierung, Raum, Rhythmus und Ausrichtung auf ein zugrunde liegendes Raster. Die erfolgreiche Bereitstellung dieser Tools ist wichtig, damit Benutzer einen Informationsbildschirm schnell verstehen können. Um diese Verwendung von Typografie zu unterstützen, führte Ice Cream Sandwich eine neue Typenfamilie namens Roboto ein, die speziell für die Anforderungen der Benutzeroberfläche und hochauflösender Bildschirme entwickelt wurde.

Das aktuelle TextView-Framework bietet Roboto in dünnen, leichten, regelmäßigen und fetten Gewichten sowie einen kursiven Stil für jedes Gewicht. Das Framework bietet auch die Roboto Condensed-Variante in regulären und fetten Gewichten sowie einen kursiven Stil für jedes Gewicht.

Nach ICS enthält Android den Roboto-Schriftstil. Lesen Sie mehr Roboto

BEARBEITEN 2

Mit der Einführung der Support Library 26 unterstützt Android jetzt standardmäßig benutzerdefinierte Schriftarten. Sie können neue Schriftarten in res / fonts einfügen, die entweder in XML oder programmgesteuert einzeln auf TextViews eingestellt werden können. Die Standardschriftart für die gesamte Anwendung kann auch durch die Festlegung auf diese styles.xml Der Androide Entwicklerdokumentation hat eine klare Führung verändert werden hier

CommonsWare
quelle
6
Keine Möglichkeit, Schriftarten in XML festzulegen? Warum?
Jonny
5
@Jonny Das kannst du eigentlich. Sie erstellen eine Klasse, die TextView erweitert und setTypeface vom Konstruktor aus aufruft.
Mark Phillip
Wie geht das im XML-Layout?
M. Usman Khan
2
@usman: Sie würden eine Drittanbieter-Bibliothek wie Kalligraphie benötigen: github.com/chrisjenx/Calligraphy
CommonsWare
Das Festlegen der Schriftart mithilfe von Java-Code ist aufgrund mehrerer Zeilen schwierig. Ich habe eine Bibliothek zum Festlegen benutzerdefinierter Schriftarten erstellt. Sie können eine Bibliotheksnutzung in dieser Antwort finden stackoverflow.com/a/42001474/4446392
Chathura Jayanath
254

Laden Sie zuerst die .ttfDatei der gewünschten Schriftart herunter ( arial.ttf). Legen Sie es in den assets Ordner. (Erstellen Sie im Ordner "Assets" einen neuen Ordner mit dem Namen " Schriftarten" und platzieren Sie ihn darin.) Verwenden Sie den folgenden Code, um die Schriftart auf Ihre Datei anzuwenden TextView:

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);
HjK
quelle
Sehr geehrter Mayur, gibt es eine Empfehlung, wo Sie diese .ttf-Dateien erhalten können?
Einzelgänger
3
Sehr geehrter @lonelearner, Sie können kostenlose Schriftarten (.ttf) auf 1001freefonts.com herunterladen oder einfach "Kostenlose Schriftarten"
googeln
10
Informationen zu Benutzern von Android Studio, die keinen Ordner "Assets" finden können, finden Sie in dieser Frage . Kurze Antwort : src/main/assets/fonts/.
Adamdport
51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
Android Girl
quelle
33

Möglicherweise möchten Sie eine statische Klasse erstellen , die alle Schriftarten enthält. Auf diese Weise erstellen Sie die Schriftart nicht mehrmals, was sich negativ auf die Leistung auswirken kann . Stellen Sie einfach sicher, dass Sie einen Unterordner mit dem Namen " Schriftarten " unter dem Ordner " Assets " erstellen .

Mach so etwas wie:

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;

}
}

Auf diese Weise können Sie die Schriftart von überall in Ihrer Anwendung abrufen.

Daniel L.
quelle
1
Super Kerl! Das ist die Schönheit von OOP. Gute Arbeit! :)
Joshua Michael Waggoner
Wie benutze ich diese Klasse?
Jack
Sie müssen diesen Code in Ihr Projekt einfügen, ihn an Ihre Schriftarten anpassen und dann die statische Methode getTypeface (..) von überall in Ihrer App verwenden.
Daniel L.
Ich habe eine ähnliche Lösung verwendet, aber Caching hinzugefügt, um die Leistung zu verbessern. Sind Sie auf jeden Fall auf eine Situation gestoßen, in der die Schriftart auf einigen Telefonen funktioniert und auf anderen nicht?
RJFares
20

Best Practice aller Zeiten

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: (Wo res / values ​​platziert werden soll )

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

Wie benutzt man:

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

Hoffe das wird dir helfen.

Hiren Patel
quelle
1
Warum ist die Unterklasse von TextView die beste Vorgehensweise?
Stealth Rabbi
@Stealth Rabbi, hier können wir benutzerdefinierte Schriftarten nur per XML übergeben, ohne dass für jede Textansicht ein spezieller Java-Code geschrieben werden muss.
Hiren Patel
Dafür gibt es eine Bibliothek. Fügen Sie einfach Ihre Schriftart unter dem Asset-Ordner hinzu und deklarieren Sie sie in XML. github.com/febaisi/CustomTextView
febaisi
Ihre Bibliothek sieht gut aus, aber das einzige Problem ist, dass es für Android 21+ ist
loloof64
17

Die obigen Antworten sind richtig. Stellen Sie einfach sicher, dass Sie einen Unterordner mit dem Namen "Schriftarten" unter dem Ordner "Assets" erstellen, wenn Sie diesen Code verwenden.

VJ Vélan Solutions
quelle
1
Ihr Kommentar ist überflüssig. Die obige Erklärung sagt genau das, was Sie gesagt haben, und mehr ...
Joshua Michael Waggoner
14

Eine andere Möglichkeit, die Erstellung von Schriftarten zu konsolidieren ...

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

Und dann in Ihrer Aktivität zu verwenden ...

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

Wohlgemerkt, diese doppelt überprüfte Sperrsprache mit dem flüchtigen Feld funktioniert nur mit dem in Java 1.5+ verwendeten Speichermodell korrekt.

Chris Aitchison
quelle
Warum hat diese Antwort nur 1 Gegenstimme und die obige 15? Was macht den anderen besser? Mir scheint, dieser ist der einfachere nach dem Singleton-Prinzip ...?
Koen Demonie
Ich habe gerade gesehen, dass Sie Ihren Konstruktor öffentlich haben, ich würde ihn privat machen, da Sie keinen Zugriff darauf benötigen. Du benutzt sowieso deine inneren Schriftarten ...
Koen Demonie
Sollte unbedingt ein privater Konstruktor sein. Gut entdeckt :) Wird bearbeitet!
Chris Aitchison
12

Es wird empfohlen, die Android Support Library Version 26.0.0 oder höher zu verwenden.

SCHRITT 1: Schriftdatei hinzufügen

  1. In res Ordner neu erstellen Schriftressourcenverzeichnis
  2. Schriftartdatei hinzufügen ( .ttf , .orf )

Wenn beispielsweise die Schriftartdatei helvetica_neue.ttf lautet, wird R.font.helvetica_neue generiert

SCHRITT 2: Erstellen Sie eine Schriftfamilie

  1. Fügen Sie im Schriftartenordner eine neue Ressourcendatei hinzu
  2. Fügen Sie jede Schriftartdatei, jeden Stil und jedes Gewichtsattribut in das Element ein.

Beispielsweise:

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

SCHRITT 3: Verwenden Sie es

In XML-Layouts:

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

Oder fügen Sie dem Stil Schriftarten hinzu:

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

Weitere Beispiele finden Sie in der Dokumentation:

Arbeiten mit Schriftarten

Marek Rzeźniczek
quelle
7

Es ist ein bisschen alt, aber ich habe die Klasse CustomFontLoader ein wenig verbessert und wollte sie teilen, damit sie hilfreich sein kann. Erstellen Sie einfach eine neue Klasse mit diesem Code.

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

Verwenden Sie dann einfach diesen Code in Ihrer Textansicht:

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

Ich habe endlich eine sehr einfache Lösung dafür gefunden.

  1. Verwenden Sie diese Support-Bibliotheken in Gradle auf App-Ebene .

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. Erstellen Sie dann ein Verzeichnis mit dem Namen "font" im Ordner res

  3. Legen Sie Schriftarten (ttf) -Dateien in dieses Schriftartenverzeichnis, beachten Sie die Namenskonventionen [egname sollte keine Sonderzeichen, Großbuchstaben und Leerzeichen oder Tabulatoren enthalten]
  4. Verweisen Sie danach wie folgt auf diese Schriftart aus XML

            <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 diesem Beispiel ist times_new_roman_test eine Schriftart-ttf-Datei aus diesem Schriftartenverzeichnis

Shamsul Arefin Sajib
quelle
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();
    }

}

Auf diese Weise können Sie eine Ansicht erstellen, die von TextView erbt und setTypeface für den Konstruktor aufruft.

Charlie-Blake
quelle
1
Hallo, warum wird WeakReference verwendet, um das TypeFace-Objekt zu speichern?
Fauler
3

Wenn Ihre Schriftart darin gespeichert ist, res/asset/fonts/Helvetica.ttfverwenden Sie Folgendes:

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

Wenn Ihre Schriftartdatei darin gespeichert ist, res/font/helvetica.ttfverwenden Sie Folgendes:

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
Pankaj Lilan
quelle
2
Vielen Dank, suchten nach dem Teil, wo Sie es im res-Ordner hatten!
Mikkel Larsen
2

Holen Sie sich die Schriftart aus dem Asset und setzen Sie sie auf alle untergeordneten Elemente

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) {
 }
 } 
Manian Rezaee
quelle
2
  1. Klasse hinzufügen 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. zur Assets Library-Schriftart hinzufügen
    Geben Sie hier die Bildbeschreibung ein


  1. add to attrs.xml, Die Zahlen sollten in der Reihenfolge in der Array-Klasse sein.

    <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. Wählen Sie eine Schriftart aus der Liste
    Geben Sie hier die Bildbeschreibung ein
David
quelle
Müssen Sie diese Klasse in MainActivity instanziieren? Weil es für mich nichts ändert.
Tobias Mayr
1

Android verwendet die Roboto-Schriftart, eine wirklich gut aussehende Schriftart mit verschiedenen Gewichten (normal, leicht, dünn, komprimiert), die auf Bildschirmen mit hoher Dichte großartig aussehen.

Überprüfen Sie den folgenden Link, um die Roboto-Schriftarten zu überprüfen:

Verwendung von Roboto im XML-Layout

Zurück zu Ihrer Frage: Wenn Sie die Schriftart für alle Textansichten / Schaltflächen in Ihrer App ändern möchten , fügen Sie den folgenden Code in Ihre styles.xml ein, um die Roboto-light- Schriftart zu verwenden:

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

Und vergessen Sie nicht, 'AppTheme' in Ihrer AndroidManifest.xml zu verwenden

<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>
Chandler
quelle
0

Vielleicht etwas einfacher:

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

(Beachten Sie, dass dieser Code nicht getestet wurde, aber im Allgemeinen sollte dieser Ansatz gut funktionieren.)

trans
quelle