Jak ustawić niestandardową czcionkę dla całej aplikacji w systemie Android?


83

Czy można ustawić niestandardową czcionkę w aplikacji na Androida?

Wypróbowałem to, co jest tutaj opublikowane , ale nie wiem, gdzie jest moja extends Applicationklasa ...

Jakaś pomoc?

EDYTOWAĆ:

Wypróbowałem następujące:

  • Dodaj folder zasobów i wstaw czcionkę do środka, jak pokazano tutaj:

wprowadź opis obrazu tutaj

  • Dodaj nową klasę, która pochodzi od Application

  • Zadzwoń do tej nowej klasy z mojego AndroidManifest.xml.

  • Poszedłem do swojego stylu i dodałem go.

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>

Ale moja czcionka nadal się nie zmienia ... Masz jakiś pomysł?

Następnie MyAppwywoływana jest klasa. Ale bez wpływu na moje czcionki ...

EDIT2: Zdałem sobie sprawę, że moje przyciski stosują niestandardową czcionkę po ustawieniu niestandardowego stylu dla moich przycisków. Oto mój niestandardowy styl przycisku:

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

A oto jak to wygląda teraz:

wprowadź opis obrazu tutaj

Więc: mój przycisk stosuje styl, ale nie TextView. Masz jakiś pomysł, dlaczego moja niestandardowa czcionka nie jest stosowana do wszystkich elementów w aplikacji?


link, który podałeś, jest naprawdę pomocny w rozwiązaniu problemu.
— Androider,

Wiem, myślę, że moje rozwiązanie jest tam ... Ale kiedy tworzę klasę, która rozszerza się z Application, nie mogę sprawić, by działała, ponieważ mówi, że moja klasa nigdy nie jest używana ...
— Sonhja,

kasy jeszcze kilka linków w mojej odpowiedzi, wydaje się być pomocny, jeszcze jedno mój pierwszy link jest naprawdę lepiej, Dzięki
— Androider

Odpowiedzi:


50

Napisz zajęcia

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

teraz następną rzeczą jest w AndroidManifest.xml dla tagu aplikacji podaj nazwę swojej klasy aplikacji. W tym przypadku jest to MyApp

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

Dlatego przy każdym otwarciu aplikacji wywoływana byłaby metoda onCreate klasy MyApp i ustawiana byłaby czcionka.

Zaktualizuj Umieść plik czcionki w obszarze asset / fonts / your_font_file.ttf

Umieść tę linię w metodzie onCreate swojej klasy aplikacji (MyApp)

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

Plik źródłowy dla 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);
            }
        }
    }
}

Teraz zaktualizuj plik style.xml

umieść poniższą linię swojego stylu, który jest zawarty w Twojej działalności w pliku manifestu

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

Mam nadzieję że to pomoże


Daj mi znać swoją wersję systemu operacyjnego Android, na którym testujesz. Zauważyłem, że w Lollipopie musimy zrobić więcej tweeksów
— Nitin Mesta

Proszę sprawdzić poniższy link, aby znaleźć rozwiązanie dla Lollipopa i poprzednich wersji Androida: ( stackoverflow.com/a/36206275/2268466 )
— blueware

zmienia całą czcionkę aplikacji w wyskakującej wiadomości, oknie ostrzeżenia, nie chcę w tym
— używać

1
Mam wątpliwości, wielu producentów zezwala użytkownikowi na zmianę czcionek w całym systemie z poziomu ustawień, czy ta zmiana również zastępuje nasz typ czcionki, który ustawiliśmy programowo?
— Bhuro

A co z ustawieniem wielu czcionek?
— Gaurav Mandlik

82

EDYTOWAĆ

uk.co.chrisjenx:calligraphyLib nie jest bardziej konserwowany, ponieważ alternatywa dla najnowszej wersji Androida jest teraz https://github.com/InflationX/Calligraphy

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

Dodaj własne czcionki do zasobów /

Stosowanie

Dla domyślnej czcionki

Zdefiniuj domyślną czcionkę za pomocą CalligraphyConfig w swojej klasie Application w metodzie #onCreate () i przekaż ją do CalligraphyInterceptor, którą dodajesz do konstruktora ViewPump.

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

Wstrzyknij w kontekst: zawiń kontekst działania:

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

Styl niestandardowy

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

Motyw

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

Nie jest bardziej utrzymywany przez deweloperów poniżej rozwiązania


W systemie Android jest wspaniała biblioteka niestandardowych czcionek: Kaligrafia
Oto przykład, jak z niej korzystać.

W Gradle musisz umieścić ten wiersz w pliku build.gradle swojej aplikacji:

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

Następnie utwórz klasę rozszerzającą Application i napisz ten kod:

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

Powinieneś zrobić na asset / a "New Directory" "fonts" (patrz poniżej), więc w tym kodzie "twoja ścieżka do czcionki" powinna mieć postać "fonts / SourceSansPro-Regular.ttf". (To tylko „czcionki…”, a nie „/ fonts ..” lub „zasoby…”)

A w klasie activity umieść tę metodę przed onCreate:

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

I ostatnia rzecz, którą twój plik manifestu powinien wyglądać tak:

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

I zmieni całą aktywność na Twoją czcionkę! to proste i czyste!

Na Zasobach kliknij prawym przyciskiem myszy Nowy katalog, nazwij go „czcionkami”. W wyszukiwarce umieść tam .ttfpliki czcionek.

wprowadź opis obrazu tutaj

Nie zapomnij również dodać poniżej dwóch wierszy w attrs.xml, jeśli nie masz pliku attrs.xml, utwórz nowy plik w values.xml

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>

Używam ttf, ale jestem prawie pewien, że .otf również będzie działać i najlepsza lokalizacja, aby umieścić go w folderze zasobów.
— Rajesh Nasit

Umieść to w rozszerzeniu Klasa aplikacji CalligraphyConfig.initDefault (new CalligraphyConfig.Builder () .setDefaultFontPath ("fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()); Nie zapomnij też dodać poniżej dwóch wierszy w values.xml <attr format = "string" name = "fontPath" /> <item name = "calligraphy_tag_id" type = "id" />
— Rajesh Nasit

cześć @rajesh! powinieneś kliknąć „Edytuj” i dodać to do swojej świetnej odpowiedzi! masz rację, powinny to być pliki .ttf , przepraszam.
— Fattie

1
Możesz użyć fragmentu maksymalnie. Więc ta liczba działań zostanie zmniejszona.
— Rajesh Nasit

1
@Pawan zrobić jeden krok - zdefiniować prostą klasę bazową gdzie attachBaseContext(..)jest realizowany, a następnie wszystkie moje zajęcia z realizacji projektu (gdzie chcę tego niestandardowej czcionki) rozszerzenie tej klasy podstawowej
— Gene Bo

65

Wszystko co zrobiłem to:

1: Dodano „nowy katalog zasobów” do folderu RES, Wybrano TYP ZASOBU jako „czcionkę” z podanej listy rozwijanej, nazwano nowy katalog „czcionką” i zapisano. NOWY KATALOG ZASOBÓW

2: Dodano mój „custom_font.ttf” do właśnie utworzonego folderu FONT.

3: Dodano moją niestandardową czcionkę do motywu podstawowego aplikacji w STYLES.XML

STYLES.XML

GOTOWE.


4
Musisz także utworzyć rodzinę czcionek. Potem zadziałało dla mnie. Szczegóły tutaj: developer.android.com/guide/topics/ui/look-and-feel/…
— keybee

zadziałało dla mnie bez konieczności tworzenia rodziny czcionek. Jednak musiałem użyć wersji Gradle> 3 i zbudować narzędzia oraz obsługiwać biblioteki ustawione na 27> @keybee
— Numanqmr

Działało świetnie, nawet bez rodziny czcionek
— Julian Alberto

czy wiesz, jak zmienić to programowo?
— majov

@majov sprawdź powyższą odpowiedź przez #Rajeesh. to powinno ci pomóc!
— Numanqmr

12

Możesz to zrobić za pomocą Android SDK teraz, jako oficjalny kanał YouTube Developer dla Androida opublikowany w zestawie / 2017 tutaj .

Wymaga poziomu interfejsu API 26 (Android 8 Oreo) lub nowszego.

Wystarczy umieścić plik czcionki w res/fontfolderze i odwołać się do niego TextViewna wypadek, gdybyś potrzebował konkretnego z android:fontFamilyatrybutem.

Jeśli chcesz mieć podstawową czcionkę w całej aplikacji, po prostu umieść

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

w Twoim styles.xml

Jeśli chcesz, możesz pobrać niestandardową czcionkę z Android Studio i w podróży. Wszystko to można znaleźć wraz ze szczegółami na powyższym filmie.


Ta opcja dotyczy interfejsu API 26 i nowszych. Not 16+
— Perfect Square

co powiesz na naprawę API 23 +?
— Raju yourPepe

12

Android zapewnia prostsze i najlepsze rozwiązania, które są obsługiwane na poziomie API 14 przez Support Library 26+. Czcionki w XML Obsługuje również opcję rodziny czcionek . Wymagany import: implementation "com.android.support:support-compat:<26+ version>"

Wykonaj te proste czynności, a rodzina czcionek zostanie zastosowana w Twojej aplikacji bez żadnych przeszkód:

  1. Utwórz katalog czcionek wewnątrz res
  2. Wklej plik czcionek do czcionki
  3. Kliknij prawym przyciskiem myszy folder czcionek i przejdź do Nowy> Plik zasobów czcionek. Zostanie wyświetlone okno New Resource File.
  4. Dodaj następujące atrybuty
<?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. W powyższym pliku xml. Używaj aplikacji tylko do korzystania z biblioteki pomocy. W przeciwnym razie możesz użyć Androida, jeśli Twoja aplikacja jest przeznaczona dla interfejsu API na poziomie 26+.
  2. Teraz przejdź do swojego styles.xml i umieść poniżej linię swojego głównego stylu.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Ważne: używaj AppCompatActivity tylko wtedy, gdy używasz biblioteki obsługi.
  4. Lub użyj poniżej, aby programowo ustawić krój pisma

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    

W ten sposób nadaje się do aktualnej funkcji zasobów czcionek systemu Android. Dzięki.
— azwar_akbar

2

Wygląda na to, że używasz android:fontFamilyzamiast android:typefacew swoim styles.xml.

Spróbuj wymienić

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

z

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

1
Jak mam to połączyć z moją aplikacją? Kto od tego rozciąga?
— Sonhja

Cóż, rozszerzając Application, po prostu tworzysz podklasę klasy swojej aplikacji Application. Więc nie musisz go podłączać.
— Suhas

Co mówi, że nigdy nie jest używane?
— Suhas

Czy dodałeś również <item name="android:typeface">default</item>linię <style name="AppTheme" parent="AppBaseTheme">w res -> values -> styles.xmlpliku swojej aplikacji, zgodnie z sugestią w tym samym poście SO?
— Suhas

Tak, i to też nie działa. Właśnie to umieściłem w mojej edycji ... :(
— Sonhja,

2

Jeśli zastosujesz się do pierwszego tematu, powinno to zadziałać: Tutaj

Tak, z refleksją. To działa ( na podstawie tej odpowiedzi ):

(Uwaga: jest to obejście z powodu braku obsługi niestandardowych czcionek, więc jeśli chcesz zmienić tę sytuację, zrób gwiazdkę, aby zagłosować tutaj na problem z Androidem). Uwaga: nie zostawiaj komentarzy „ja też” na ten temat, każdy, kto go obejrzał, otrzyma e-maila, gdy to zrobisz. Więc po prostu „gwiazdkuj”, proszę.

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

Następnie musisz przeładować kilka domyślnych czcionek, na przykład w klasie aplikacji:

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

Lub oczywiście, jeśli używasz tego samego pliku czcionki, możesz to poprawić, aby załadować go tylko raz.

Jednak staram się po prostu zastąpić jeden z nich, powiedzieć „MONOSPACE”, a następnie ustawić styl, aby wymusić szeroki zakres kroju czcionki:

<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

Zbadałem raporty w komentarzach, że to nie działa i wydaje się być niezgodne z motywem android: Theme.Material.Light.

Jeśli ten motyw nie jest dla Ciebie ważny, użyj starszego motywu, np .:

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

2
  1. Na początku, należy kliknąć prawym przyciskiem myszy zasobów projektowych, której nazwa resnastępnie z newopcją wyboru Android Resource Directoryi wybierz fontformularz Resource typei naciśnij OK, to stworzy katalog czcionek do umieszczania w nim czcionek.

wprowadź opis obrazu tutaj

  1. Umieść .ttftam pliki czcionek.

wprowadź opis obrazu tutaj

  1. Przejdź do pliku stylu projektu, który istnieje w następującej ścieżce res/values/styles.xml i dodaj takie style:

    <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. Przejdź do swojego kodu i napisz taką klasę, aby zmienić czcionkę całej aplikacji:

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

    Ponieważ czcionki powinny być ustawione osobno dla każdej czynności, wolę napisać dla niej klasę, aby kod był bardziej przejrzysty.

  3. Następnie wywołaj metodę klasy przed aktywnością onCreate super.onCreate(savedInstanceState):

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

    Pamiętaj, że jeśli chcesz zmienić czcionkę w trakcie działania , napisz wybraną czcionkę w SharedPreferenceslub itp., A następnie przekaż wybraną czcionkę do wszystkich czynności setFontjak powyżej.


1

Utwórz folder zasobów w folderze głównym. Dodaj folder czcionek w nim. dodaj swój plik .ttf w folderze czcionek.

Dodaj następujące elementy do motywu aplikacji:

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

Utwórz klasę jako TypefaceUtil

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

Wywołaj to w klasie aplikacji lub w działaniu Launchera

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf

0

Najpierw utwórz nową klasę, która zastępuje widok, który chcesz dostosować. (np. chcesz mieć przycisk z niestandardowym krojem czcionki? Rozszerz Button). Na przykład:

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

Teraz, jeśli go nie masz, dodaj dokument XML pod res/values/attrs.xmli dodaj:

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

Okej, więc pomijając to, wróćmy do parseAttributes()metody z wcześniejszej:

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

Teraz wszystko gotowe. Możesz dodać więcej atrybutów do wszystkiego (możesz dodać kolejny dla stylu kroju - pogrubienie, kursywa, itp.), Ale teraz zobaczmy, jak go użyć:

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

xmlns:customLinia może być naprawdę coś, ale konwencja jest co pokazano powyżej. Liczy się to, że jest unikalny i dlatego używana jest nazwa pakietu. Teraz wystarczy użyć custom:przedrostka dla swoich atrybutów i android:przedrostka dla atrybutów Androida.

Ostatnia sprawa: jeśli chcesz to wykorzystać w stylu ( res/values/styles.xml), należy nie dodać xmlns:customlinię. Po prostu odwołaj się do nazwy atrybutu bez przedrostka:

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

0

Próbowałem też nadpisywania czcionek, ale ostatecznie nie jest to niezawodne rozwiązanie, niestety zastępowanie czcionek wymaga więcej. Możesz poczekać, aż pojawi się Android O z niestandardową czcionką lub skorzystać z biblioteki innej firmy.

Ostatnim rozwiązaniem, na które się natknąłem, była ta biblioteka Caligraphy , która była łatwa do zainicjowania i pozwalała używać dowolnej liczby czcionek. Sprawdzając jego kod źródłowy, zrozumiałem, dlaczego samo zastępowanie czcionek nie zadziała, więc nawet jeśli nie planujesz go używać, polecam przeczytanie go raz.

Powodzenia


Tak… może. W każdym razie daj nam znać, jeśli znalazłeś przyczynę tego problemu, naprawdę by to docenił. Nie mogłem znaleźć rozwiązania, nawet czytając podstawowe kody.
— Keivan Esbati

0

Wypróbuj poniższy kod, działa dla mnie, mam nadzieję, że ci też pomoże.

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

Teraz rozszerz tę BaseActivity na dowolne działanie lub możesz utworzyć tę samą klasę dla fragmentu, jeśli używasz.

Uwaga: - Jeśli chcesz ustawić niektóre z widoków na inny krój, musisz ustawić to programowo, jak poniżej

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

Więc spróbuj i daj mi znać, czy mógłbym ci dalej pomóc


0

Będzie to obejście dla kotlina

Streszczenie rozwiązania https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Krok pierwszy

Umieść plik czcionki w asset / fonts / your_font_file.ttf i utwórz klasę kotlin o nazwie 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")
        }
    }
}

Krok drugi Następnie w twoimonCreate

val typefaceUtil = TypefaceUtil()

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

Krok trzeci

dodaj to do swojego stylu

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

0

Nazwy czcionek należy pisać małymi literami, aby były widoczne w aplikacji i pracy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.