Wie kann ich eine benutzerdefinierte Schriftart für eine ganze Anwendung in Android festlegen?

82

Ist es möglich, eine benutzerdefinierte Schriftart in einer Android-Anwendung festzulegen?

Ich habe versucht , was geschrieben ist hier , aber ich weiß nicht, wo meine extends ApplicationKlasse ist ...

Irgendeine Hilfe?

BEARBEITEN:

Ich habe folgendes versucht:

  • Fügen Sie einen Assets-Ordner hinzu und fügen Sie die Schriftart wie folgt ein:

Geben Sie hier die Bildbeschreibung ein

  • Fügen Sie eine neue Klasse hinzu, die sich von erstreckt Application

  • Nennen Sie diese neue Klasse von meinem AndroidManifest.xml.

  • Ich ging zu meinem Stil und fügte ihn hinzu.

MyApp.java:

public class MyApp extends Application {
  @Override
  public void onCreate() {
     super.onCreate();
    FontsOverride.setDefaultFont(this, "DEFAULT", "raleway_regular.ttf");
    //  This FontsOverride comes from the example I posted above
  }
  }

AndroidManifest.xml:

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

styles.xml:

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:fontFamily">default</item>
 </style>

Aber meine Schriftart ändert sich immer noch nicht ... irgendeine Idee?

Dann wird die MyAppKlasse aufgerufen. Aber keine Auswirkung auf meine Schriftarten ...

EDIT2: Ich habe festgestellt, dass meine Schaltflächen die benutzerdefinierte Schriftart anwenden, nachdem ich einen benutzerdefinierten Stil für meine Schaltflächen festgelegt habe. Hier ist mein benutzerdefinierter Schaltflächenstil:

<style name="MyButtonStyle" parent="Widget.AppCompat.Button">
    <item name="textAllCaps">false</item>
    <item name="android:textAllCaps">false</item>
</style>

Und so sieht es jetzt aus:

Geben Sie hier die Bildbeschreibung ein

Also: Mein Button wendet den Stil an, aber nicht den TextView. Haben Sie eine Idee, warum meine benutzerdefinierte Schriftart nicht für alle Elemente in der Anwendung angewendet wird?

Sonhja
quelle
Der von Ihnen angegebene Link ist für Ihr Problem sehr hilfreich.
Androider
Ich weiß, ich denke, meine Lösung ist da ... Aber wenn ich eine Klasse erstelle, die sich von Application aus erstreckt, kann ich sie nicht zum
Laufen
Checkout einige weitere Links in meiner Antwort, scheint hilfreich zu sein, eine weitere Sache, mein erster Link ist wirklich besser, Danke
Androider

Antworten:

49

Schreibe eine Klasse

public class MyApp extends Application{
// Put the onCreate code as you obtained from the post link you reffered
}

Als nächstes finden Sie in AndroidManifest.xml das Anwendungs-Tag. Geben Sie den Namen für Ihre Anwendungsklasse an. In diesem Fall ist es MyApp

<application
android:name=".MyApp"
...
>
...
</application>

Wenn die App geöffnet wird, wird die onCreate-Methode der MyApp-Klasse aufgerufen und die Schriftart festgelegt.

Update Fügen Sie die Schriftartdatei unter assets / fonts / your_font_file.ttf ein

Fügen Sie diese Zeile unter die Methode onCreate Ihrer Anwendungsklasse (MyApp) ein.

TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/your_font_file.ttf");

Quelldatei für TypefaceUtil

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     *
     * @param context                    to work with assets
     * @param defaultFontNameToOverride  for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {

        final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Map<String, Typeface> newMap = new HashMap<String, Typeface>();
            newMap.put("serif", customFontTypeface);
            try {
                final Field staticField = Typeface.class
                        .getDeclaredField("sSystemFontMap");
                staticField.setAccessible(true);
                staticField.set(null, newMap);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            try {
                final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
                defaultFontTypefaceField.setAccessible(true);
                defaultFontTypefaceField.set(null, customFontTypeface);
            } catch (Exception e) {
                Log.e(TypefaceUtil.class.getSimpleName(), "Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
            }
        }
    }
}

Aktualisieren Sie nun Ihre style.xml-Datei

Fügen Sie in die folgende Zeile Ihren Stil ein, der für Ihre Aktivität in der Manifestdatei enthalten ist

  <item name="android:typeface">serif</item>

Hoffe das hilft

Nitin Mesta
quelle
Bitte teilen Sie mir Ihre Android-Version mit, auf der Sie testen. Ich habe in Lutscher beobachtet, dass wir sicher mehr Wochen machen müssen
Nitin Mesta
Bitte überprüfen Sie den folgenden Link für die Lösung für Lollipop und frühere Android-Versionen: ( stackoverflow.com/a/36206275/2268466 )
Blueware
Es ändert alle App-Schriftarten in Toast-Nachricht, Warnungsdialog, ich möchte keine benutzerdefinierte Schriftart in diesem
Adil
1
Ich habe Zweifel, viele Hersteller erlauben dem Benutzer, Schriftarten systemweit aus den Einstellungen heraus zu ändern. Überschreibt diese Änderung auch unseren von uns programmgesteuert festgelegten Schrifttyp?
Bhuro
82

BEARBEITEN

uk.co.chrisjenx:calligraphyLib wird nicht mehr für die neueste Android-Version gewartet. Die Alternative ist jetzt https://github.com/InflationX/Calligraphy

dependencies {
    implementation 'io.github.inflationx:calligraphy3:3.1.1'
    implementation 'io.github.inflationx:viewpump:2.0.3'
}

Fügen Sie Ihre benutzerdefinierten Schriftarten zu Assets / hinzu

Verwendung

Für die Standardschriftart

Definieren Sie Ihre Standardschriftart mit CalligraphyConfig in Ihrer Anwendungsklasse in der Methode #onCreate () und übergeben Sie sie an den CalligraphyInterceptor, den Sie Ihrem ViewPump-Builder hinzufügen.

@Override
public void onCreate() {
    super.onCreate();
    ViewPump.init(ViewPump.builder()
        .addInterceptor(new CalligraphyInterceptor(
                new CalligraphyConfig.Builder()
                    .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf")
                    .setFontAttrId(R.attr.fontPath)
                    .build()))
        .build());
    //....
}

In den Kontext injizieren: Wickeln Sie den Aktivitätskontext ein:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase));
}

Benutzerdefinierter Stil

<style name="TextViewCustomFont">
    <item name="fontPath">fonts/RobotoCondensed-Regular.ttf</item>
</style>

Für Thema

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>
</style>

<style name="AppTheme.Widget"/>

<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
    <item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>
</style>

Nicht mehr von Developers Below Solution gepflegt


Es gibt eine großartige Bibliothek für benutzerdefinierte Schriftarten in Android: Kalligraphie
Hier ist ein Beispiel für die Verwendung.

In Gradle müssen Sie diese Zeile in die build.gradle-Datei Ihrer App einfügen:

        dependencies {
            compile 'uk.co.chrisjenx:calligraphy:2.2.0'
        }

Erstellen Sie dann eine Klasse, die Application erweitert, und schreiben Sie diesen Code:

        public class App extends Application {
            @Override
            public void onCreate() {
                super.onCreate();

                CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                                .setDefaultFontPath("your font path")
                                .setFontAttrId(R.attr.fontPath)
                                .build()
                );
            }
        } 

Sie sollten für Assets / ein "neues Verzeichnis" "Schriftarten" erstellt haben (siehe unten), daher sollte in diesem Code "Ihr Schriftpfad" "Schriftarten / SourceSansPro-Regular.ttf" sein. (Es ist nur "Schriftarten ..." nicht "/ Schriftarten .." oder "Assets ..")

Und in der Aktivitätsklasse setzen Sie diese Methode vor onCreate:

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

Und das Letzte, was Ihre Manifestdatei so aussehen sollte:

        <application
           .
           .
           .
           android:name=".App">

Und es wird die gesamte Aktivität in Ihre Schriftart ändern! es ist einfach und sauber!

Klicken Sie unter "Assets" mit der rechten Maustaste auf "Neues Verzeichnis" und nennen Sie es "Schriftarten". Im Finder legen Sie die .ttfSchriftdateien dort ab.

Geben Sie hier die Bildbeschreibung ein

Vergessen Sie auch nicht, die folgenden zwei Zeilen in attrs.xml hinzuzufügen. Wenn Sie keine attrs.xml-Datei haben, erstellen Sie eine neue Datei in values.xml

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>
Rajesh Nasit
quelle
Ich benutze ttf, aber ich bin mir ziemlich sicher, dass .otf auch funktioniert und der beste Ort ist, um es in den Assets-Ordner zu legen.
Rajesh Nasit
Fügen Sie dies in die erweiterte Anwendungsklasse CalligraphyConfig.initDefault (new CalligraphyConfig.Builder () .setDefaultFontPath ("fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()) ein. Vergessen Sie auch nicht, unten zwei Zeilen in values.xml hinzuzufügen. <Attr format = "string" name = "fontPath" /> <item name = "calligraphy_tag_id" type = "id" />
Rajesh Nasit
hi @rajesh! Sie sollten auf "Bearbeiten" klicken und dies zu Ihrer großartigen Antwort hinzufügen! Sie haben Recht, es sollten .ttf- Dateien sein, sorry.
Fattie
1
Sie können das Fragment so maximal wie möglich verwenden. So wird die Anzahl der Aktivitäten reduziert.
Rajesh Nasit
1
@Pawan, um es einen Schritt zu tun - Ich definiere eine einfache Basisklasse, in der attachBaseContext(..)implementiert wird, und dann erweitern alle meine Projektaktivitätsklassen (wo ich diese benutzerdefinierte Schriftart möchte) diese Basisklasse
Gene Bo
63

Alles was ich getan habe war:

1: Dem RES-Ordner wurde "neues Ressourcenverzeichnis" hinzugefügt, der RESOURCE-TYP als "Schriftart" aus der angegebenen Dropdown-Liste ausgewählt, das neue Verzeichnis "font" genannt und gespeichert. NEUES RESSOURCENVERZEICHNIS

2: Meine "custom_font.ttf" wurde dem gerade erstellten FONT-Ordner hinzugefügt.

3: Meine benutzerdefinierte Schriftart wurde im Anwendungsbasis-Design in STYLES.XML hinzugefügt

STYLES.XML

ERLEDIGT.

Numanqmr
quelle
4
Sie müssen auch eine Schriftfamilie erstellen. Danach hat es bei mir funktioniert. Details hier: developer.android.com/guide/topics/ui/look-and-feel/…
keybee
Es hat bei mir funktioniert, ohne dass ich eine Schriftfamilie erstellen musste. Allerdings musste ich Gradle Version> 3 verwenden und Tools erstellen und Bibliotheken unterstützen, die auf 27> @keybee
Numanqmr
Arbeitete großartig für mich, auch ohne Schriftfamilie
Julian Alberto
Wissen Sie, wie Sie es programmgesteuert ändern können?
Majov
@majov überprüfen Sie die Antwort oben von #Rajeesh. das sollte dir helfen!
Numanqmr
12

Sie können dies jetzt mit dem Android SDK tun, da der offizielle YouTube-Kanal für Android-Entwickler im Set / 2017 hier veröffentlicht wurde .

Benötigt API Level 26 (Android 8 Oreo) und höher.

Sie müssen nur Ihre Schriftartdatei in den res/fontOrdner legen und in Ihrem Ordner referenzieren, TextViewfalls Sie eine bestimmte mit dem android:fontFamilyAttribut benötigen .

Wenn Sie eine Basisschrift für Ihre gesamte App wünschen, geben Sie diese einfach ein

<item name="android:fontFamily">@font/yourfontname</item> 

in deiner styles.xml

Sie können eine benutzerdefinierte Schriftart von Android Studio herunterladen und unterwegs, wenn Sie möchten. All dies finden Sie mit Details im obigen Video.

Francisco Nin
quelle
Diese Option gilt für API 26 und höher. Nicht 16+
Perfect Square
Wie wäre es mit einer Korrektur für API 23 +?
Raju yourPepe
12

Android bietet einfachere und beste Lösungen, die von der Support Library 26+ über API Level 14 unterstützt werden. Schriftarten in XML Unterstützt auch die Option für die Schriftfamilie . Erforderlicher Import: implementation "com.android.support:support-compat:<26+ version>"

Befolgen Sie diese einfachen Schritte, und die Schriftfamilie wird ohne Hürde in Ihrer App angewendet:

  1. Erstellen Sie ein Schriftverzeichnis in res
  2. Fügen Sie Ihre Schriftartdatei in die Schriftart ein
  3. Klicken Sie mit der rechten Maustaste auf den Schriftartenordner und gehen Sie zu Neu> Schriftressourcendatei. Das Fenster Neue Ressourcendatei wird angezeigt.
  4. Fügen Sie folgende Attribute hinzu
<?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>
  1. In der obigen XML-Datei. Verwenden Sie die App nur, um die Support-Bibliothek zu verwenden. Andernfalls können Sie Android verwenden, wenn Ihre App auf API-Level 26+ abzielt.
  2. Gehen Sie nun zu Ihrer styles.xml und setzen Sie die folgende Zeile in Ihren Hauptstil.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Wichtig: Verwenden Sie AppCompatActivity nur, wenn Sie die Support-Bibliothek verwenden.
  4. Oder verwenden Sie unten, um die Schrift programmgesteuert einzustellen

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    
Kuldeep Sakhiya
quelle
Auf diese Weise eignet es sich für die aktuelle Android Font Resource-Funktion. Vielen Dank.
azwar_akbar
2

Scheint, als würden Sie android:fontFamilystatt android:typefacein Ihrem verwenden styles.xml.

Versuchen Sie es zu ersetzen

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:fontFamily">default</item>
</style>

mit

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:typeface">default</item>
</style>
Suhas
quelle
1
Und wie verbinde ich es mit meiner Anwendung? Wer erstreckt sich davon?
Sonhja
Durch die Erweiterung Applicationerstellen Sie einfach eine Unterklasse der Klasse Ihrer Anwendung Application. Sie müssen es also nicht anschließen.
Suhas
Was sagt, dass es nie benutzt wird?
Suhas
Haben Sie auch eine <item name="android:typeface">default</item>Zeile in <style name="AppTheme" parent="AppBaseTheme">die res -> values -> styles.xmlDatei Ihrer App eingefügt, wie im selben SO-Beitrag vorgeschlagen?
Suhas
Ja, und es funktioniert auch nicht. Das ist genau das, was ich in meine Bearbeitung
eingefügt
2

Wenn Sie dem ersten Thema folgen, sollte dies funktionieren: Hier

Ja mit Nachdenken. Dies funktioniert ( basierend auf dieser Antwort ):

(Hinweis: Dies ist eine Problemumgehung, da benutzerdefinierte Schriftarten nicht unterstützt werden. Wenn Sie diese Situation ändern möchten, stimmen Sie bitte ab, um das Android-Problem hier zu verbessern.) Hinweis: Hinterlassen Sie keine "Ich auch" -Kommentare zu diesem Thema. Jeder, der es angestarrt hat, erhält dabei eine E-Mail. Also bitte einfach "stern".

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {

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

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

Sie müssen dann die wenigen Standardschriftarten überladen, beispielsweise in einer Anwendungsklasse:

public final class Application extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    }
}

Wenn Sie dieselbe Schriftartdatei verwenden, können Sie diese natürlich verbessern, um sie nur einmal zu laden.

Ich neige jedoch dazu, nur einen zu überschreiben, z. B. "MONOSPACE", und dann einen Stil einzurichten, um die Anwendung dieser Schriftart zu erzwingen:

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Light">
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:typeface">monospace</item>
    </style>
</resources>

API 21 Android 5.0

Ich habe die Berichte in den Kommentaren untersucht, dass es nicht funktioniert und es mit dem Thema Android nicht kompatibel zu sein scheint: Theme.Material.Light.

Wenn Ihnen dieses Thema nicht wichtig ist, verwenden Sie ein älteres Thema, z.

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>
Robin Delaporte
quelle
1

Erstellen Sie den Ordner "Assets" im Ordner "main folder.add fonts". Fügen Sie Ihre .ttf-Datei im Ordner fonts hinzu.

Fügen Sie Ihrem App-Thema Folgendes hinzu:

 <item name="android:fontFamily">@font/roboto_regular</item>
    <item name="fontFamily">@font/roboto_regular</item>

Klasse als TypefaceUtil erstellen

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

import java.lang.reflect.Field;

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {
            Log.e("Can not set","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

Rufen Sie es in der Anwendungsklasse oder in der Launcher-Aktivität auf

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
Pratibha Sarode
quelle
1
  1. Zu Beginn sollten Sie mit der rechten Maustaste auf Ihre Projektressourcen klicken, deren Namen resdann aus der newOption Formular auswählen Android Resource Directoryund auswählen font, Resource typeund auf OK klicken. Dadurch wird ein Schriftartenverzeichnis erstellt, in dem Ihre Schriftarten platziert werden.

Geben Sie hier die Bildbeschreibung ein

  1. Legen Sie Ihre .ttfSchriftdateien dort ab.

Geben Sie hier die Bildbeschreibung ein

  1. Gehen Sie zur Projektstil-Datei, die im folgenden Pfad vorhanden ist, res/values/styles.xml und fügen Sie solche Stile hinzu:

    <style name="SansSerifFont">
        <item name="android:fontFamily">sans-serif</item>
    </style>
    
    <style name="OpenSansFont">
        <item name="android:fontFamily">@font/open_sans</item>
    </style>
    
    <style name="IranianSansFont">
        <item name="android:fontFamily">@font/iranian_sans</item>
    </style>
    
    <style name="BYekanFont">
        <item name="android:fontFamily">@font/b_yekan</item>
    </style>
    
    <style name="DroidArabicFont">
        <item name="android:fontFamily">@font/droid_arabic</item>
    </style>
    
  2. Gehen Sie zu Ihrem Code und schreiben Sie eine Klasse wie diese, um die gesamte App-Schriftart zu ändern:

    public class AppFontManager {
    
        private AppCompatActivity appCompatActivity;
    
        public static final String SANS_SERIF_APP_FONT = "sans_serif";
        public static final String B_YEKAN_APP_FONT = "b_yekan";
        public static final String DROID_ARABIC_APP_FONT = "droid_arabic";
        public static final String IRANIAN_SANS_APP_FONT = "iranian_sans";
        public static final String OPEN_SANS_APP_FONT = "open_sans";
    
        public AppAppearanceManager(AppCompatActivity appCompatActivity) {
            this.appCompatActivity = appCompatActivity;
        }
    
        public void setFont(String fontName){
    
            switch (fontName){
    
                case SANS_SERIF_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.SansSerifFont, true);
                    break;
                }
    
                case B_YEKAN_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.BYekanFont, true);
                    break;
                }
    
                case DROID_ARABIC_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.DroidArabicFont, true);
                    break;
                }
    
                case IRANIAN_SANS_APP_FONT:{
                appCompatActivity.getTheme().applyStyle(R.style.IranianSansFont, true);
                    break;
                }
    
                case OPEN_SANS_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.OpenSansFont, true);
                    break;
                }
            }
        }
    }
    

    Da Schriftarten für jede Aktivität separat festgelegt werden sollten , schreibe ich lieber eine Klasse dafür, um saubereren Code zu erhalten.

  3. Rufen Sie dann die Klassenmethode vor der Aktivität onCreate auf super.onCreate(savedInstanceState):

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        new AppAppearanceManager(this).setFont(APP_DEFAULT_FONT);
        super.onCreate(savedInstanceState);
    // Do you stuff there...
    }
    

    Denken Sie daran, dass Sie, wenn Sie die Schriftart zur Laufzeit ändern möchten , eine ausgewählte Schriftart in SharedPreferencesusw. schreiben und dann die ausgewählte Schriftart an alle Aktivitäten setFontwie oben übergeben.

Mohsen Pakzad
quelle
0

Erstellen Sie zunächst eine neue Klasse, die die Ansicht überschreibt, die Sie anpassen möchten. (zB möchten Sie einen Button mit einer benutzerdefinierten Schrift? Erweitern Button). Zum Beispiel:

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

Wenn Sie noch keines haben, fügen Sie unter ein XML-Dokument hinzu res/values/attrs.xmlund fügen Sie Folgendes hinzu:

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

Okay, wenn das aus dem Weg ist, kehren wir zu der parseAttributes()Methode von früher zurück:

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

Jetzt sind Sie fertig. Sie können für fast alles weitere Attribute hinzufügen (Sie können ein weiteres für typefaceStyle hinzufügen - fett, kursiv usw.), aber jetzt wollen wir sehen, wie es verwendet wird:

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

Die xmlns:customLinie kann wirklich alles sein, aber die Konvention ist die oben gezeigte. Was zählt ist, dass es einzigartig ist und deshalb der Paketname verwendet wird. Jetzt verwenden Sie nur das custom:Präfix für Ihre Attribute und das android:Präfix für Android-Attribute.

Eine letzte Sache: Wenn Sie dies in einem style ( res/values/styles.xml) verwenden möchten , sollten Sie die Zeile nicht hinzufügen xmlns:custom. Verweisen Sie einfach auf den Namen des Attributs ohne Präfix:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>
Archit Goel
quelle
0

Ich habe auch versucht, Schriftarten zu überschreiben, aber am Ende ist es keine zuverlässige Lösung. Leider erfordern das Überschreiben von Schriftarten mehr als das. Sie können entweder warten, bis Android O mit benutzerdefinierter Schriftart angezeigt wird, oder eine Bibliothek eines Drittanbieters verwenden.

Die letzte Lösung, auf die ich gestoßen bin , war diese Bibliothek Caligraphy , die einfach zu initiieren war und es Ihnen ermöglichte, so viele Schriftarten zu verwenden, wie Sie möchten. Beim Überprüfen des Quellcodes habe ich verstanden, warum das Überschreiben von Schriftarten nicht funktioniert. Selbst wenn Sie nicht vorhaben, ihn zu verwenden, empfehle ich, ihn einmal durchzulesen.

Viel Glück

Keivan Esbati
quelle
Ja ... vielleicht. Wie auch immer, lassen Sie uns wissen, wenn Sie einen Grund für dieses Problem gefunden haben. Würde es wirklich schätzen. Ich konnte keine Lösung finden, selbst wenn ich zugrunde liegende Codes las.
Keivan Esbati
0

Versuchen Sie unten Code, es funktioniert für mich, hoffe, es wird Ihnen auch helfen.

public class BaseActivity extends AppCompatActivity {

private Typeface typeace;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    typeace = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name));
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    overrideFonts(this,getWindow().getDecorView());
}

private 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(typeace);
        } else if (v instanceof EditText ) {
            ((EditText) v).setTypeface(typeace);
        } else if (v instanceof Button) {
            ((Button) v).setTypeface(typeace);
        }
    } catch (Exception e) {
 }
 }
}

Erweitern Sie diese BaseActivity jetzt auf eine Ihrer Aktivitäten, oder Sie können dieselbe Klasse für Fragmente erstellen, wenn Sie sie verwenden.

Hinweis: - Wenn Sie einen Teil der Ansichtsschrift anders einstellen möchten, müssen Sie dies programmgesteuert wie folgt einstellen

private Typeface typeface;
typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold));
tvUserName.setTypeface(typeface);

Probieren Sie es aus und lassen Sie es mich wissen, wenn ich Ihnen weiterhelfen könnte

Bhavnik
quelle
0

Eine Lösung für Kotlin wird dies sein

Kern der Lösung https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Schritt eins

Fügen Sie die Schriftartdatei unter assets / fonts / your_font_file.ttf ein und erstellen Sie eine Kotlin-Klasse mit dem Namen TypeFaceUtil

   class TypefaceUtil{

    fun overridefonts(context: Context, defaultFontToOverride:String, customFontFileNameInAssets:String){
        try {
            val customTypeface = Typeface.createFromAsset(context.assets,customFontFileNameInAssets)
            val defaultTypefaceField = Typeface::class.java.getDeclaredField(defaultFontToOverride)
            defaultTypefaceField.isAccessible = true
            defaultTypefaceField.set(null,customTypeface)
        }catch (e:Exception){
            Timber.e("Cannot set font $customFontFileNameInAssets instead of $defaultFontToOverride")
        }
    }
}

Schritt zwei Dann in Ihrem aufonCreate

val typefaceUtil = TypefaceUtil()

typefaceUtil.overridefonts(this,"SERIF","fonts/font_file.ttf")

Schritt drei

Fügen Sie dies Ihrem Stil hinzu

<item name="android:typeface">serif</item>
Johnyoat
quelle
0

Schriftnamen sollten in Kleinbuchstaben angegeben werden, damit sie in Anwendung und Arbeit angezeigt werden.

Mazhar Ali
quelle