Как установить собственный шрифт для всего приложения в Android?

83

Можно ли установить собственный шрифт в приложении для Android?

Я пробовал то, что написано здесь , но не знаю, где находится мой extends Applicationкласс ...

Любая помощь?

РЕДАКТИРОВАТЬ:

Я пробовал следующее:

  • Добавьте папку с ресурсами и вставьте шрифт внутрь, как показано здесь:

введите описание изображения здесь

  • Добавьте новый класс, который расширяется от Application

  • Назовите этот новый класс из моего AndroidManifest.xml.

  • Я подошел к своему стилю и добавил его.

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>

Но мой шрифт все еще не меняется ... есть идеи?

Затем MyAppвызывается класс. Но на мои шрифты никакого эффекта ...

EDIT2: я понял, что мои кнопки применяют настраиваемый шрифт после того, как я установил собственный стиль для своих кнопок. Вот мой собственный стиль кнопки:

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

А вот как это выглядит сейчас:

введите описание изображения здесь

Итак: моя кнопка применяет стиль, но не TextView. Есть идеи, почему мой собственный шрифт не применяется ко всем элементам приложения?

Sonhja
источник
Ссылка, которую вы предоставили, действительно помогает решить вашу проблему.
Androider
Я знаю, я думаю, что мое решение есть ... Но когда я создаю класс, который расширяется от Application, я не могу заставить его работать, поскольку он говорит, что мой класс никогда не используется ...
Сонхья
проверить еще несколько ссылок в моем ответе, кажется полезным, еще одна вещь, моя первая ссылка действительно лучше, спасибо
Androider

Ответы:

50

Напишите класс

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

Теперь следующая вещь находится в AndroidManifest.xml для тега приложения, дающего имя для вашего класса приложения. В данном случае это MyApp

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

Таким образом, всякий раз, когда приложение открывается, будет вызываться метод onCreate класса MyApp, и шрифт будет установлен.

Обновите файл шрифта. Поместите его в папку assets / fonts / your_font_file.ttf.

Поместите эту строку в метод onCreate вашего класса приложения (MyApp)

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

Исходный файл для 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);
            }
        }
    }
}

Теперь обновите файл style.xml

поместите строку ниже в свой стиль, который включен для вашей деятельности в файл манифеста

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

Надеюсь это поможет

Нитин Места
источник
Сообщите мне свою версию ОС Android, на которой вы тестируете. Я заметил, что в отношении леденца на палочке нам нужно сделать еще кое-что,
Нитин Места
По следующей ссылке вы
найдете
он меняет весь шрифт приложения в всплывающем сообщении, диалоговом окне предупреждения, я не хочу использовать пользовательский шрифт в этом
Адиль
1
Я сомневаюсь, что многие производители позволяют пользователю изменять шрифты в масштабе всей системы из настроек. Это изменение также отменяет наш тип шрифта, который мы устанавливаем программно?
Bhuro
А как насчет установки нескольких шрифтов?
Гаурав Мандлик
82

РЕДАКТИРОВАТЬ

uk.co.chrisjenx:calligraphyLib больше не поддерживается для последней версии Android, теперь альтернатива https://github.com/InflationX/Calligraphy

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

Добавьте свои собственные шрифты в активы /

Применение

Для шрифта по умолчанию

Определите шрифт по умолчанию с помощью CalligraphyConfig в своем классе Application в методе #onCreate () и передайте его в CalligraphyInterceptor, который вы добавляете в свой конструктор 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());
    //....
}

Ввести в контекст: обернуть контекст действия:

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

Пользовательский стиль

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

Для темы

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

Больше не поддерживается разработчиками. Ниже решения


В Android есть отличная библиотека для пользовательских шрифтов: Каллиграфия.
Вот пример ее использования.

В Gradle вам нужно поместить эту строку в файл build.gradle вашего приложения:

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

А затем создайте класс, расширяющий Application, и напишите этот код:

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

Вы должны были создать на assets / «Новый каталог» «шрифты» (см. Ниже), поэтому в этом коде «путь к вашему шрифту» должен быть «fonts / SourceSansPro-Regular.ttf». (Это просто «шрифты ...», а не «/ шрифты ..» или «активы ..»)

И в классе активности поместите этот метод перед onCreate:

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

И последнее, что ваш файл манифеста должен выглядеть так:

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

И это изменит всю активность на ваш шрифт! это просто и чисто!

В Assets вы должны щелкнуть правой кнопкой мыши New Directory, назовите его «fonts». В искателе поместите .ttfтуда файлы шрифтов.

введите описание изображения здесь

Также не забудьте добавить две строки ниже в attrs.xml, если у вас нет файла attrs.xml, создайте новый файл в values.xml

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>
Раджеш Насит
источник
Я использую ttf, но я почти уверен, что .otf также будет работать, и это лучшее место для его размещения в папке с ресурсами.
Раджеш Насит
Поместите это в расширенный класс приложения CalligraphyConfig.initDefault (новый CalligraphyConfig.Builder () .setDefaultFontPath ("fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()); Также не забудьте добавить две строки ниже в values.xml <attr format = "string" name = "fontPath" /> <item name = "calligraphy_tag_id" type = "id" />
Раджеш Насит
привет @rajesh! вы должны нажать «Изменить» и добавить это к своему отличному ответу! Вы правы, это должны быть файлы .ttf , извините.
Fattie
1
Вы можете максимально использовать фрагмент. Так что количество действий будет уменьшено.
Раджеш Насит
1
@Pawan, чтобы сделать это за один шаг - я определяю простой базовый класс, в котором attachBaseContext(..)он реализован, а затем все классы Activity моего проекта (где мне нужен этот настраиваемый шрифт) расширяют этот базовый класс
Джин Бо
65

Все, что я сделал, это:

1: Добавлен «новый каталог ресурсов» в папку RES, выбран ТИП РЕСУРСА как «шрифт» из раскрывающегося списка, назван новый каталог «шрифт» и сохранен. НОВЫЙ КАТАЛОГ РЕСУРСОВ

2: Добавлен мой "custom_font.ttf" в только что созданную папку FONT.

3: Добавлен собственный шрифт в базовую тему приложения в STYLES.XML.

STYLES.XML

СДЕЛАННЫЙ.

Numanqmr
источник
4
Вам также необходимо создать семейство шрифтов. После этого у меня все заработало. Подробности здесь: developer.android.com/guide/topics/ui/look-and-feel/…
keybee
это сработало для меня без необходимости создавать семейство шрифтов. Однако мне пришлось использовать Gradle версии> 3 и установить инструменты сборки и библиотеки поддержки на 27> @keybee
Numanqmr
У меня отлично поработало, даже без семейства шрифтов
Джулиан Альберто
ты знаешь как это программно изменить?
majov
@majov проверьте ответ #Rajeesh выше. это должно вам помочь!
Numanqmr
12

Вы можете сделать это с помощью SDK для Android прямо сейчас, поскольку официальный канал YouTube для разработчиков Android опубликован в set / 2017 здесь .

Требуется уровень API 26 (Android 8 Oreo) и выше.

Вам просто нужно поместить файл шрифта в res/fontпапку и ссылаться на них в вашем TextViewслучае, если вам нужен конкретный файл с android:fontFamilyатрибутом.

Если вам нужен базовый шрифт для всего приложения, просто поместите

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

в вашем styles.xml

Вы можете загрузить собственный шрифт из Android Studio и на ходу, если хотите. Все это вы можете найти в видео выше.

Франсиско Нин
источник
Этот вариант предназначен для API 26 и выше. Not 16+
Perfect Square
как насчет исправления для API 23 +?
Raju yourPepe
12

Android предоставляет более простые и лучшие решения, которые поддерживаются на уровне API 14 библиотекой поддержки 26+. Шрифты в XML. Он также поддерживает вариант семейства шрифтов . Обязательный импорт: implementation "com.android.support:support-compat:<26+ version>"

Выполните следующие простые шаги, и семейство шрифтов будет применено в вашем приложении без каких-либо препятствий:

  1. Создайте каталог шрифтов внутри res
  2. Вставьте файл шрифтов внутрь font
  3. Щелкните правой кнопкой мыши папку шрифтов и выберите «Создать»> «Файл ресурсов шрифта». Откроется окно «Новый файл ресурсов».
  4. Добавить следующие атрибуты
<?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. В приведенном выше файле xml. Используйте приложение только для использования библиотеки поддержки. В противном случае вы можете использовать Android, если ваше приложение нацелено на уровень API 26+.
  2. Теперь перейдите в свой файл styles.xml и поместите строку ниже в свой основной стиль.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Важно: используйте AppCompatActivity, только если вы используете библиотеку поддержки.
  4. Или используйте ниже, чтобы программно установить шрифт

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    
Кулдип Сахия
источник
Этот способ подходит для текущей функции Android Font Resource. Благодарю.
azwar_akbar
2

Похоже, вы используете android:fontFamilyвместо android:typefaceсвоего styles.xml.

Попробуйте заменить

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

с участием

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:typeface">default</item>
</style>
Сухас
источник
1
А как связать со своим приложением? Кто от этого простирается?
Sonhja
Что ж, расширяя, Applicationвы просто создаете подкласс класса вашего приложения Application. Так что подключать его не нужно.
Сухас
Что говорит, что он никогда не использовался?
Сухас
Вы также добавили <item name="android:typeface">default</item>строку <style name="AppTheme" parent="AppBaseTheme">в res -> values -> styles.xmlфайл своего приложения, как это предлагается в том же сообщении SO?
Сухас
Да и тоже не работает. Это именно то, что я вставил в свою правку ... :(
Sonhja
2

Если вы следите за первой темой, это должно сработать: Здесь

Да, с отражением. Это работает ( на основе этого ответа ):

(Примечание: это обходной путь из-за отсутствия поддержки пользовательских шрифтов, поэтому, если вы хотите изменить эту ситуацию, нажмите звездочку, чтобы проголосовать за проблему с Android здесь). Примечание. Не оставляйте комментариев «я тоже» по этой проблеме, все, кто ее рассматривал, получат электронное письмо, когда вы это сделаете. Так что просто поставьте звезду, пожалуйста.

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

Затем вам нужно перегрузить несколько шрифтов по умолчанию, например, в классе приложения:

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

Или, конечно, если вы используете тот же файл шрифта, вы можете улучшить его, загрузив его только один раз.

Однако я предпочитаю просто переопределить одно, скажем "MONOSPACE", а затем настроить стиль, чтобы заставить это приложение гарнитуры шрифта широко:

<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

Я исследовал сообщения в комментариях, что он не работает и несовместим с темой android: Theme.Material.Light.

Если эта тема для вас не важна, используйте старую тему, например:

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>
Робин Делапорте
источник
2
  1. Вначале вы должны щелкнуть правой кнопкой мыши ресурсы вашего проекта, имя которых, resзатем из newопции выбрать Android Resource Directoryи выбрать fontформу Resource typeи нажать ОК, это создаст каталог шрифтов для размещения в нем ваших шрифтов.

введите описание изображения здесь

  1. Поместите .ttfтуда свои файлы шрифтов.

введите описание изображения здесь

  1. Перейдите в файл стиля проекта, который существует по следующему пути, res/values/styles.xml и добавьте такие стили:

    <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. Перейдите к своему коду и напишите такой класс для изменения шрифта всего приложения:

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

    Поскольку шрифты должны устанавливаться отдельно для каждого действия, я предпочитаю написать для него класс, чтобы код был более чистым.

  3. Затем вызовите метод класса перед действием onCreate super.onCreate(savedInstanceState):

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

    Помните, что если вы хотите изменить шрифт во время выполнения , напишите выбранный шрифт SharedPreferencesи т. Д., Затем передайте выбранный шрифт всем действиям, setFontкак указано выше.

Мохсен Пакзад
источник
1

Создайте папку с активами в основной папке. Добавьте в нее папку со шрифтами. добавьте файл .ttf в папку шрифтов.

Добавьте в свою тему приложения следующее:

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

Создать класс как 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);
        }
    }
}

Вызовите его в классе приложения или в действии Launcher

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
Пратибха Сароде
источник
0

Сначала создайте новый класс, который переопределяет любой вид, который вы хотите настроить. (например, хотите кнопку с настраиваемым шрифтом? Расширить Button). Например:

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

Теперь, если у вас его нет, добавьте XML-документ res/values/attrs.xmlи добавьте:

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

Итак, разобравшись с этим, давайте вернемся к parseAttributes()методу, описанному ранее:

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

Теперь все готово. Вы можете добавить дополнительные атрибуты для чего угодно (вы можете добавить еще один для typefaceStyle - жирный, курсив и т. Д.), Но теперь давайте посмотрим, как его использовать:

<?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:customЛиния действительно может быть что угодно, но соглашение является то , что показано выше. Важно то, что он уникален, и поэтому используется имя пакета. Теперь вы просто используете custom:префикс для своих атрибутов и android:префикс для атрибутов Android.

И последнее: если вы хотите использовать это в style ( res/values/styles.xml), вам не следует добавлять xmlns:customстроку. Просто укажите имя атрибута без префикса:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>
Archit Goel
источник
0

Я тоже пробовал переопределить шрифт, но, в конце концов, это не надежное решение, к сожалению, переопределение шрифтов требует большего. Вы можете дождаться выхода Android O с настраиваемым шрифтом или использовать стороннюю библиотеку.

Последним решением, с которым я столкнулся, была эта библиотека Caligraphy , которую было легко запустить и которая позволяла использовать столько шрифтов, сколько захотите. Проверяя его исходный код, я понял, почему просто переопределение шрифтов не сработает, поэтому, даже если вы не планируете его использовать, я рекомендую прочитать его один раз ..

Удачи

Кейван Эсбати
источник
Да .. возможно. В любом случае дайте нам знать, если вы нашли причину этой проблемы, был бы очень признателен. Я не мог найти решение, даже читая базовые коды.
Кейван Эсбати
0

Попробуйте код ниже, он работает для меня, надеюсь, он вам тоже поможет.

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

Теперь распространите эту BaseActivity на любую из ваших Activity, или вы можете создать тот же класс для фрагмента, если используете.

Примечание: - Если вы хотите установить для некоторых видов другой шрифт, вы должны установить это программно, как показано ниже.

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

Так что попробуйте и дайте мне знать, если бы я мог вам помочь

Бхавник
источник
0

Обходом для котлина будет это

Суть решения https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Шаг первый

Поместите файл шрифта в assets / fonts / your_font_file.ttf и создайте класс kotlin с именем 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")
        }
    }
}

Шаг второй Затем в вашемonCreate

val typefaceUtil = TypefaceUtil()

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

Шаг третий

добавьте это в свой стиль

<item name="android:typeface">serif</item>
Johnyoat
источник
0

Названия шрифтов должны быть в нижнем регистре, чтобы они отображались в приложении и работали.

Мажар Али
источник