Benutzerdefinierte Schriftarten und XML-Layouts (Android)

174

Ich versuche, ein GUI-Layout mithilfe von XML-Dateien in Android zu definieren. Soweit ich herausfinden kann, kann nicht angegeben werden, dass Ihre Widgets eine benutzerdefinierte Schriftart (z. B. eine, die Sie in Assets / font / platziert haben) in XML-Dateien verwenden sollen, und Sie können nur die vom System installierten Schriftarten verwenden.

Ich weiß, dass ich im Java-Code die Schriftart jedes Widgets manuell mithilfe eindeutiger IDs ändern kann. Alternativ könnte ich alle Widgets in Java durchlaufen, um diese Änderung vorzunehmen, aber dies wäre wahrscheinlich sehr langsam.

Welche anderen Optionen habe ich? Gibt es bessere Möglichkeiten, Widgets mit einem benutzerdefinierten Erscheinungsbild zu erstellen? Ich möchte nicht besonders die Schriftart für jedes neue Widget, das ich hinzufüge, manuell ändern müssen.

DrDefrost
quelle
68
DrDefrost - bitte akzeptieren Sie einige Antworten, Sie erhalten weitere Antworten auf dieser Website.
SK9
1
Hier ist noch eine ähnliche Frage: stackoverflow.com/questions/9030204/…
Vins
Aktualisiert 05/2017: "Die Support Library 26.0 Beta bietet Unterstützung für die Funktion" Schriftarten in XML "auf Geräten mit Android API Version 14 und höher." Siehe: developer.android.com/preview/features/…
albert c braun

Antworten:

220

Sie können TextView erweitern, um benutzerdefinierte Schriftarten festzulegen, wie ich hier erfahren habe .

TextViewPlus.java:

package com.example;

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

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 tf = null;
        try {
        tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;
        }

        setTypeface(tf);  
        return true;
    }

}

attrs.xml: (in res / values)

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

main.xml:

<?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/com.example"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.example.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="saxmono.ttf">
    </com.example.TextViewPlus>
</LinearLayout>

Sie würden "saxmono.ttf" in den Assets- Ordner legen .

UPDATE 8/1/13

Bei dieser Methode gibt es ernsthafte Speicherprobleme. Siehe den Kommentar von chedabob unten.

Peter
quelle
5
Das sieht gut aus, aber ich erhalte eine Fehlermeldung, wenn ich versuche, "TextViewPlus" in der Datei main.xml zu verwenden. Ich erhalte Folgendes: - Fehler: Fehler beim Parsen von XML: ungebundenes Präfix - Das Präfix "foo" für das Attribut "foo: customFont", das einem Elementtyp "supportLibs.TextViewPlus" zugeordnet ist, ist nicht gebunden.
Majjoodi
79
Zu beachten ist, dass dadurch Dutzende von TypeFace-Objekten generiert und Speicherplatz verbraucht werden. Es gibt einen Fehler in Android vor 4.0, der TypeFaces nicht richtig freigibt. Am einfachsten ist es, einen TypeFace-Cache mit einer HashMap zu erstellen. Dadurch wurde die Speichernutzung in meiner App von über 120 MB auf 18 MB gesenkt. code.google.com/p/android/issues/detail?id=9904
Chedabob
7
@Majjoodi: Das passiert normalerweise, wenn Sie vergessen, den 2. Namespace zu Ihrem Layout hinzuzufügen:xmlns:foo="http://schemas.android.com/apk/res/com.example
Theo
11
SEHR WICHTIG - Ich möchte nur den Rat von Chedabob verdoppeln. Wenn Sie es nicht befolgen, tritt in Pre-ICS ein Speicherverlust auf. Es gibt nur wenige Lösungen, eine davon befindet sich in dem von chedabob bereitgestellten Link, eine andere hier: stackoverflow.com/questions/8057010/listview-memory-leak . Peter - bitte aktualisieren Sie Ihre Antwort - es ist großartig, aber nicht vollständig
Michał K
1
Wie lege ich dieses benutzerdefinierte Attribut in styles.xml zusätzlich zu anderen Textansichtsattributen wie Breite und Höhe fest?
Loeschg
35

Ich bin 3 Jahre zu spät für die Party :( Dies könnte jedoch für jemanden nützlich sein, der über diesen Beitrag stolpern könnte.

Ich habe eine Bibliothek geschrieben, die Schriften zwischenspeichert und es Ihnen ermöglicht, benutzerdefinierte Schriften direkt aus XML anzugeben. Die Bibliothek finden Sie hier .

So würde Ihr XML-Layout aussehen, wenn Sie es verwenden.

<com.mobsandgeeks.ui.TypefaceTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    geekui:customTypeface="fonts/custom_font.ttf" />
Ragunath Jawahar
quelle
Hey @ Ragunath-jawahar, wie würde ich die Bibliothek für ein Gradle-Projekt importieren? Ich habe es versucht, compile 'com.mobsandgeeks:android-typeface-textview:1.0'aber das hat nicht funktioniert.
Aimango
1
Sie benötigen einen AAR, um ihn auf diese Weise verwenden zu können. Es ist noch nicht da. Sie können die Quellen kopieren und vorerst ein Android Studio Library-Projekt erstellen.
Ragunath Jawahar
2
Woher kommt dein Geekui-Tag?
Sefirosu
3
Aus dem im übergeordneten Tag angegebenen Namespace -xmlns:geekui="http://schemas.android.com/apk/res-auto"
Ragunath Jawahar
1
@ MuhammedRefaat, ja, das tut es :)
Ragunath Jawahar
18

Dies kann etwas spät sein, aber Sie müssen eine Singleton-Klasse erstellen, die die benutzerdefinierte Schriftart zurückgibt, um Speicherverluste zu vermeiden.

TypeFace-Klasse:

public class OpenSans {

private static OpenSans instance;
private static Typeface typeface;

public static OpenSans getInstance(Context context) {
    synchronized (OpenSans.class) {
        if (instance == null) {
            instance = new OpenSans();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
        }
        return instance;
    }
}

public Typeface getTypeFace() {
    return typeface;
}
}

Benutzerdefinierte Textansicht:

public class NativelyCustomTextView extends TextView {

    public NativelyCustomTextView(Context context) {
        super(context);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

}

Per XML:

<com.yourpackage.views.NativelyCustomTextView
            android:id="@+id/natively_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="20dp"
            android:text="@string/natively"
            android:textSize="30sp" /> 

Programmatisch:

TextView programmaticallyTextView = (TextView) 
       findViewById(R.id.programmatically_text_view);

programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
                .getTypeFace());
Leonardo Cardoso
quelle
Scheint zur Laufzeit zu funktionieren, aber soll es auch im Designer funktionieren?
Magnus Johansson
Sicher. Sie können als XML verwenden. @ Magnus
Leonardo Cardoso
Ich denke, Sie haben es falsch verstanden, es scheint in der Entwurfszeit nicht zu funktionieren (Designer-Vorschau). (xml! = Designer). Es funktioniert einwandfrei, wie in der zur Laufzeit kompilierten XML-Layoutdatei angegeben. Wie auch immer, ich bin mit dieser Erweiterung github.com/danh32/Fontify , die für meine Bedürfnisse viel besser funktioniert (es mehrere Schriftstile, normal, fett usw. sowie verschiedene Schriftarten Namen sowie andere Steuerelemente über Textview - Unterstützung)
Magnus Johansson
2
Das getTypeFace erstellt bei jedem Aufruf eine neue Schriftart ... dies macht den Zweck des Singletons zunichte. Es sollte ein statisches Feld haben, das beim ersten Aufruf festgelegt wird und bei nachfolgenden Aufrufen den Wert des Felds zurückgibt.
Steven Pena
1
@chiwai du hast recht! Über die erste Frage braucht es das nicht. Ungefähr in der Sekunde war es ein Tippfehler.
Leonardo Cardoso
13

Alte Frage, aber ich wünschte, ich würde diese Antwort hier lesen, bevor ich mich auf die Suche nach einer guten Lösung mache. Calligraphy erweitert das android:fontFamilyAttribut, um Unterstützung für benutzerdefinierte Schriftarten in Ihrem Asset-Ordner hinzuzufügen, wie folgt:

<TextView 
  android:text="@string/hello_world"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:fontFamily="fonts/Roboto-Bold.ttf"/>

Das einzige, was Sie tun müssen, um es zu aktivieren, ist es an den Kontext der Aktivität anzuhängen, die Sie verwenden:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(new CalligraphyContextWrapper(newBase));
}

Sie können auch Ihr eigenes benutzerdefiniertes Attribut angeben, das ersetzt werden soll android:fontFamily

Es funktioniert auch in Themen, einschließlich AppTheme.

thoutbeckers
quelle
8

Verwenden von DataBinding :

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
 textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

In XML:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Schriftartdatei muss in sein assets/fonts/

Chulo
quelle
7

Wenn Sie nur eine Schriftart haben, die Sie hinzufügen möchten, und weniger Code schreiben möchten, können Sie eine dedizierte Textansicht für Ihre spezifische Schriftart erstellen. Siehe Code unten.

package com.yourpackage;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;


    public FontTextView(Context context) {
        super(context);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
}

In main.xml können Sie Ihre Textansicht jetzt folgendermaßen hinzufügen:

<com.yourpackage.FontTextView
    android:id="@+id/tvTimer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />
Tore Rudberg
quelle
Tun Sie dies auf init () und sparen Sie sich 3x den gleichen Aufruf.
Ericosg
@ericosg Ich erhalte diesen Fehler, wenn ich Ihre Lösung android.view.InflateException verwende: Binäre XML-Datei Zeile 9: Fehler beim Aufblasen der Klasse com.ascent.adwad.utils.CustomTextView
Sagar Devanga
@SagarDevanga, schwer zu helfen ohne weitere Informationen. Nehmen Sie es vielleicht so weit wie möglich und stellen Sie eine neue Frage.
Ericosg
7

Der beste Weg, dies zu tun Ab Android O Preview Release ist dieser Weg
1.) Klicken Sie mit der rechten Maustaste auf den Ordner res und gehen Sie zu Neu> Android-Ressourcenverzeichnis . Das
Fenster Neues Ressourcenverzeichnis wird angezeigt.
2.) Wählen Sie in der Liste Ressourcentyp die Schriftart aus und klicken Sie auf OK.
3.) Fügen Sie Ihre Schriftdateien in den Schriftordner ein. Die folgende Ordnerstruktur generiert R.font.dancing_script, R.font.la_la und R.font.ba_ba.
4.) Doppelklicken Sie auf eine Schriftartdatei, um eine Vorschau der Schriftarten der Datei im Editor anzuzeigen.

Als nächstes müssen wir eine Schriftfamilie erstellen

1.) Klicken Sie mit der rechten Maustaste auf den Schriftartenordner und gehen Sie zu Neu> Schriftressourcendatei . Das Fenster Neue Ressourcendatei wird angezeigt.
2.) Geben Sie den Dateinamen ein und klicken Sie auf OK . Die neue XML-Schriftartressource wird im Editor geöffnet.
3.) Fügen Sie jede Schriftartdatei, jeden Schriftstil und jedes Gewichtsattribut in das Schriftart-Tag-Element ein. Das folgende XML veranschaulicht das Hinzufügen von font-bezogenen Attributen zum XML der Schriftartressource:

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

Hinzufügen von Schriftarten zu einer Textansicht:

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

Wie aus der Dokumentation

Arbeiten mit Schriftarten

Alle Schritte sind korrekt.

jeevan s
quelle
1
Die beste Antwort! Der Dateiname der Schriftart muss in Kleinbuchstaben angegeben werden.
Dmitry
Sie können auch einen benutzerdefinierten Stil erstellen, den Sie auf Ihre Anwendung anwenden (unter der AndroidManifest-Datei) und der ALLEN Ansichten zugewiesen wird. Anstatt es beispielsweise nur in einer einzelnen Textansicht zu platzieren, hat dies keine Auswirkungen auf die Symbolleiste.
Goldenmaza
5

Erweitern Sie es TextViewund geben Sie ihm ein benutzerdefiniertes Attribut, oder verwenden Sie einfach das android: tag-Attribut, um eine Zeichenfolge mit der gewünschten Schriftart zu übergeben. Sie müssen eine Konvention auswählen und sich daran halten, da ich alle meine Schriftarten im Ordner res / assets / fonts / ablege, damit Ihre TextView-Klasse weiß, wo sie zu finden sind. Dann legen Sie in Ihrem Konstruktor die Schriftart nach dem Superaufruf einfach manuell fest.

Nathan Schwermann
quelle
4

Die einzige Möglichkeit, benutzerdefinierte Schriftarten zu verwenden, ist der Quellcode.

Denken Sie daran, dass Android auf Geräten mit sehr begrenzten Ressourcen ausgeführt wird und Schriftarten möglicherweise viel RAM benötigen. Die eingebauten Droid-Schriftarten sind speziell angefertigt und, wenn Sie bemerken, fehlen viele Zeichen und Dekorationen.

Tareq Sha
quelle
"Denken Sie daran, dass Android auf Geräten mit sehr begrenzten Ressourcen ausgeführt wird" -> dies wird immer weniger der Fall. Quad-Core-Telefon? Ja wirklich??
Sandy
9
Ich würde mehr tun, um den Kontext der Antwort von tareqHs zu berücksichtigen, die gut zweieinhalb Jahre vor Ihrem Kommentar liegt.
SK9
Der erste Teil Ihrer Antwort war möglicherweise richtig, als Sie Ihre Antwort im Jahr 2010 geschrieben haben. Letzteres ist Superfluoys und nebenbei: Droid war schlecht, 2012 von Google zugunsten von Roboto fallen gelassen. Die mangelnde Auswahl an Typografie in Android ist ein Fehler, keine Funktion. iOS bietet Entwicklern seit 2008 nach heutigen Maßstäben mehrere Schriftarten unter primitiven Geräten.
Cosmix
Diese Antwort ist nicht mehr gültig.
Martin Konecny
2

Ich könnte eine einfache Antwort auf die Frage haben, ohne die Textansicht zu erweitern und einen langen Code zu implementieren.

Code:

 TextView tv = (TextView) findViewById(R.id.textview1);
    tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf"));

Legen Sie die benutzerdefinierte Schriftartdatei wie gewohnt im Assets-Ordner ab und versuchen Sie dies. Für mich geht das. Ich verstehe nur nicht, warum Peter einen so großen Code für diese einfache Sache gegeben hat oder er seine Antwort in der alten Version gegeben hat.

San
quelle
2

Kann auch in der XML definiert werden, ohne benutzerdefinierte Klassen zu erstellen

style.xml

<style name="ionicons" parent="android:TextAppearance">
    <!-- Custom Attr-->
    <item name="fontPath">fonts/ionicons.ttf</item>
</style>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/ionicons"
        android:text=""/>
</LinearLayout>

Ein kurzer Hinweis, da ich einfach immer vergessen habe, wo die Schriftarten abgelegt werden sollen, muss sich die Schriftart darin befinden assetsund dieser Ordner befindet sich auf derselben Ebene wie resund srcin meinem Fall auf seinerassets/fonts/ionicons.ttf

Aktualisiert Root-Layout hinzugefügt, da diese Methode xmlns:app="http://schemas.android.com/apk/res-auto"funktionieren muss

Update 2 Ich habe eine Bibliothek vergessen, die ich zuvor installiert habe und die Kalligraphie heißt

norman784
quelle
Das funktioniert bei mir nicht. Wenn ich versuche, dies zu erstellen, wird folgende Fehlermeldung angezeigt: Fehler: (49, 5) Es wurde keine Ressource gefunden, die dem angegebenen Namen entspricht: attr 'fontPath'.
Stef
Versuchen Sie, xmlns:app="http://schemas.android.com/apk/res-auto"zu Ihrem Root-Layout hinzuzufügen , überprüfen Sie auch die aktualisierte Antwort
norman784
Der Fehler stammt nicht aus der XML-Layoutdatei, sondern aus der XML-Datei des Stils. Es scheint, dass es nicht "weiß", was ein fontPath ist.
Stef
Ihr Recht, vergessen, dass ich eine Bibliothek namens Calligrapy
norman784
1

Peters Antwort ist die beste, aber sie kann verbessert werden, indem Sie die Datei styles.xml von Android verwenden, um Ihre Schriftarten für alle Textansichten in Ihrer App anzupassen.

Mein Code ist hier

Jelle
quelle
1

Es gibt zwei Möglichkeiten, Schriftarten anzupassen:

!!! meine benutzerdefinierte Schriftart in assets / fonts / iran_sans.ttf

Weg 1: Refrection Typeface.class ||| bester Weg

Rufen Sie FontsOverride.setDefaultFont () in der Klasse Extend Application auf. Dieser Code bewirkt, dass alle Software-Schriftarten geändert werden, auch Toasts-Schriftarten

AppController.java

public class AppController extends Application {

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

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");

    }
}

FontsOverride.java

public class FontsOverride {

    public static void setDefaultFont(Context context, String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(), fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    }

    private static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

Weg 2: Verwenden Sie setTypeface

Für eine spezielle Ansicht rufen Sie einfach setTypeface () auf, um die Schriftart zu ändern.

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}
Rasoul Miri
quelle
0

Sie können einfach eine benutzerdefinierte Textansichtsklasse erstellen: -

Also, was Sie zuerst tun müssen, machen Sie Custom textviewKlasse, die mit erweitert AppCompatTextView.

public class CustomTextView extends AppCompatTextView {
    private int mFont = FontUtils.FONTS_NORMAL;
    boolean fontApplied;

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

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, context);
    }

    public CustomTextView(Context context) {
        super(context);
        init(null, context);
    }

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "http://schemas.android.com/apk/res-auto", "Lato-Regular.ttf",
                        -1);
            }
            Typeface typeface = getTypeface();
            int typefaceStyle = Typeface.NORMAL;
            if (typeface != null) {
                typefaceStyle = typeface.getStyle();
            }
            if (mFont > FontUtils.FONTS) {
                typefaceStyle = mFont;
            }
            FontUtils.applyFont(this, typefaceStyle);
            fontApplied = true;
        }
    }
}

Jetzt erhalten Sie jedes Mal, wenn eine benutzerdefinierte Textansicht aufgerufen wird, einen int-Wert vom Attribut int fontValue = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1).

Oder

Wir können getTypeface () auch aus der Ansicht abrufen, die wir in unserer xml ( android:textStyle="bold|normal|italic") festgelegt haben. Also mach was immer du willst.

Jetzt setzen wir eine FontUtilsbeliebige .ttf-Schriftart in unsere Ansicht.

public class FontUtils {

    public static final int FONTS = 1;
    public static final int FONTS_NORMAL = 2;
    public static final int FONTS_BOLD = 3;
    public static final int FONTS_BOLD1 = 4;

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

    static Typeface getFonts(Context context, String name) {
        Typeface typeface = TYPEFACE.get(name);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(context.getAssets(), name);
            TYPEFACE.put(name, typeface);
        }
        return typeface;
    }

    public static void applyFont(TextView tv, int typefaceStyle) {

        Context cxt = tv.getContext();
        Typeface typeface;

        if(typefaceStyle == Typeface.BOLD_ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
        } else if (typefaceStyle == Typeface.ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
        } else {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }
        if (typeface != null) {
            tv.setTypeface(typeface);
        }
    }
}
Duggu
quelle
0

Es kann hilfreich sein zu wissen, dass Sie ab Android 8.0 (API-Level 26) eine benutzerdefinierte Schriftart in XML verwenden können .

Sie können eine benutzerdefinierte Schriftart auf die folgende Anwendung anwenden.

  1. Legen Sie die Schriftart in den Ordner res/font.

  2. Bei res/values/styles.xmlVerwendung in der Anwendung Thema. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>

Vic
quelle
-5

Sie können TextView nicht erweitern, um ein Widget zu erstellen oder eines in einem Widgets-Layout zu verwenden: http://developer.android.com/guide/topics/appwidgets/index.html

Carl Whalley
quelle
1
Aha - die berühmte doppelte Verwendung des Wortes "Widget" schlägt wieder zu!
Carl Whalley