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

Я использую светлый шрифт Roboto в своем приложении. Чтобы установить шрифт, я должен добавить android:fontFamily="sans-serif-light" для каждого взгляда. Есть ли способ объявить шрифт Roboto как семейство шрифтов по умолчанию для всего приложения? Я пытался так, но это не сработало.

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

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

17 ответов

Решение

Ответ - да.

Глобал Робото лайт для TextView а также Button классы:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="RobotoButtonStyle" parent="android:Widget.Holo.Button">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

Просто выберите нужный стиль из списка themes.xml, затем создайте свой собственный стиль на основе оригинального. В конце примените стиль в качестве темы приложения.

<application
    android:theme="@style/AppTheme" >
</application>

Он будет работать только со встроенными шрифтами, такими как Roboto, но это был вопрос. Для пользовательских шрифтов (например, загружаемых из ресурсов) этот метод не будет работать.

РЕДАКТИРОВАТЬ 13/13/15

Если вы используете темы AppCompat, не забудьте удалить android: префикс. Например:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="buttonStyle">@style/RobotoButtonStyle</item>
</style>

Обратите внимание buttonStyle не содержит android: префикс, но textViewStyle должен содержать это.

С выпуском Android Oreo вы можете использовать библиотеку поддержки для достижения этой цели.

  1. Проверьте в своем приложении build.gradle, если у вас есть библиотека поддержки >= 26.0.0
  2. Добавьте папку "шрифт" в папку ресурсов и добавьте туда свои шрифты
  3. Ссылка на семейство шрифтов по умолчанию в основном стиле вашего приложения:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
       <item name="android:fontFamily">@font/your_font</item>
       <item name="fontFamily">@font/your_font</item> <!-- target android sdk versions < 26 and > 14 if theme other than AppCompat -->
    </style>
    

Проверьте https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html для получения более подробной информации.

Чтобы изменить шрифт приложения, выполните следующие действия:

  1. внутри res каталог создайте новый каталог и назовите его font,
  2. Вставьте ваш шрифт.ttf /.otf в папку шрифтов. Убедитесь, что имя шрифта состоит из строчных букв и подчеркивания.
  3. внутри res -> values -> styles.xml внутри <resources> -> <style> добавить свой шрифт <item name="android:fontFamily">@font/font_name</item>,

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

Вы можете использовать Каллиграфию для управления шрифтами с Android

https://github.com/chrisjenx/Calligraphy

ЧИТАЙТЕ ОБНОВЛЕНИЯ НИЖЕ

У меня была та же проблема с встраиванием нового шрифта, и, наконец, я получил его для работы с расширением TextView и установил внутри шрифт typefont.

public class YourTextView extends TextView {

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

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

    public YourTextView(Context context) {
        super(context);
        init();
    }

    private void init() {
        Typeface tf = Typeface.createFromAsset(context.getAssets(),
            "fonts/helveticaneue.ttf");
        setTypeface(tf);
    }
}

Вы должны изменить элементы TextView позже на с каждого элемента. И если вы используете UI-Creator в Eclipse, иногда он не показывает TextViews правильно. Была единственная вещь, которая работает для меня...

ОБНОВИТЬ

В настоящее время я использую отражение для изменения шрифтов во всем приложении без расширения TextViews. Проверьте это ТАК сообщение

ОБНОВЛЕНИЕ 2

Начиная с API уровня 26 и доступного в "библиотеке поддержки", вы можете использовать

android:fontFamily="@font/embeddedfont"

Дополнительная информация: шрифты в XML

Добавьте эту строку кода в свой файл res/value/styles.xml

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

весь стиль будет выглядеть так

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:fontFamily">@font/circular_medium</item>
</style>

замените "circle_medium" на собственное имя шрифта..

Это очень просто сделать в Android Studio.

  1. В этом методе вам необходимо подтвердить свой minsdkveriosn. Это должно быть необходимо minsdkversion >=16

  1. Создайте папку "font" внутри папки "res". В студии Android New> Folder> Font Folder.

См. Изображение:

  1. Загрузите файл шрифта в эту папку шрифтов.

Бывший:Бывший:

  1. В вашем файле style.xml в разделе style в «Базовой теме приложения» добавьте эту строку.

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

Бывший:

Не говорите о производительности, для пользовательского шрифта вы можете иметь рекурсивный цикл метода для всех видов и установить гарнитуру, если это TextView:

public class Font {
    public static void setAllTextView(ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setAllTextView((ViewGroup) child);
            } else if (child instanceof TextView) {
                ((TextView) child).setTypeface(getFont());
            }
        }
    }

    public static Typeface getFont() {
        return Typeface.createFromAsset(YourApplicationContext.getInstance().getAssets(), "fonts/whateverfont.ttf");
    }
}

Во всей вашей деятельности передайте текущую ViewGroup ей после setContentView, и все готово:

ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
Font.setAllTextView(group);

Для фрагмента вы можете сделать что-то подобное.

Просто используйте эту библиотеку, скомпилируйте ее в свой файл оценок

complie'me.anwarshahriar:calligrapher:1.0'

и использовать его в методе onCreate в основной деятельности

Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "yourCustomFontHere.ttf", true);

Это самый элегантный супер быстрый способ сделать это.

Еще один способ сделать это для всего приложения - использовать рефлексию, основанную на этом ответе.

public class TypefaceUtil {
    /**
     * Using reflection to override default typefaces
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE
     * OVERRIDDEN
     *
     * @param typefaces map of fonts to replace
     */
    public static void overrideFonts(Map<String, Typeface> typefaces) {
        try {
            final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
            if (oldFonts != null) {
                oldFonts.putAll(typefaces);
            } else {
                oldFonts = typefaces;
            }
            field.set(null, oldFonts);
            field.setAccessible(false);
        } catch (Exception e) {
            Log.e("TypefaceUtil", "Can not set custom fonts");
        }
    }

    public static Typeface getTypeface(int fontType, Context context) {
        // here you can load the Typeface from asset or use default ones
        switch (fontType) {
            case BOLD:
                return Typeface.create(SANS_SERIF, Typeface.BOLD);
            case ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.ITALIC);
            case BOLD_ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.BOLD_ITALIC);
            case LIGHT:
                return Typeface.create(SANS_SERIF_LIGHT, Typeface.NORMAL);
            case CONDENSED:
                return Typeface.create(SANS_SERIF_CONDENSED, Typeface.NORMAL);
            case THIN:
                return Typeface.create(SANS_SERIF_MEDIUM, Typeface.NORMAL);
            case MEDIUM:
                return Typeface.create(SANS_SERIF_THIN, Typeface.NORMAL);
            case REGULAR:
            default:
                return Typeface.create(SANS_SERIF, Typeface.NORMAL);
        }
    }
}

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

Typeface regular = TypefaceUtil.getTypeface(REGULAR, context);
Typeface light = TypefaceUtil.getTypeface(REGULAR, context);
Typeface condensed = TypefaceUtil.getTypeface(CONDENSED, context);
Typeface thin = TypefaceUtil.getTypeface(THIN, context);
Typeface medium = TypefaceUtil.getTypeface(MEDIUM, context);
Map<String, Typeface> fonts = new HashMap<>();
fonts.put("sans-serif", regular);
fonts.put("sans-serif-light", light);
fonts.put("sans-serif-condensed", condensed);
fonts.put("sans-serif-thin", thin);
fonts.put("sans-serif-medium", medium);
TypefaceUtil.overrideFonts(fonts);

для полной проверки примера

Это работает только для Android SDK 21 и выше, для более ранних версий проверьте полный пример

Это работа для моего проекта, источник https://gist.github.com/artem-zinnatullin/7749076

Создайте каталог шрифтов внутри папки активов, а затем скопируйте свой собственный шрифт в каталог шрифтов, например, я использую trebuchet.ttf;

Создать класс TypefaceUtil.java;

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

import java.lang.reflect.Field;
public class TypefaceUtil {

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

        }
    }
}

Изменить тему в файле styles.xml добавить ниже

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

Пример в Моем styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:typeface">serif</item><!-- Add here -->
    </style>


    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>
</resources>

Наконец, в Activity или Fragment onCreate вызовите TypefaceUtil.java

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TypefaceUtil.overrideFont(getContext(), "SERIF", "fonts/trebuchet.ttf");
    }

Android не предоставляет много способов поддержки применения шрифтов ко всему приложению (см. Эту проблему). У вас есть 4 варианта, чтобы установить шрифт для всего приложения:

  • Вариант 1: применить отражение, чтобы изменить системный шрифт
  • Вариант 2. Создание и создание подклассов пользовательских классов View для каждого View, для которого требуется собственный шрифт.
  • Вариант 3. Реализуйте View Crawler, который просматривает иерархию представлений для текущего экрана.
  • Вариант 4: использовать стороннюю библиотеку.

Подробности этих опций можно найти здесь.

просто установить шрифт приложения в normal , sans , serif или же monospace (не для пользовательского шрифта!), вы можете сделать это.

определить тему и установить android:typeface атрибут шрифта, который вы хотите использовать в styles.xml:

<resources>

    <!-- custom normal activity theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- other elements -->
        <item name="android:typeface">monospace</item>
    </style>

</resources>

применить тему ко всему приложению в AndroidManifest.xml файл:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application
        android:theme="@style/AppTheme" >
    </application>
</manifest>

Ссылка на Android

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

public static void setFont(ViewGroup layout)
{
    final int childcount = layout.getChildCount();
    for (int i = 0; i < childcount; i++)
    {
        // Get the view
        View v = layout.getChildAt(i);

        // Apply the font to a possible TextView
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Apply the font to a possible EditText
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Recursively cicle into a possible child layout
        try {
            ViewGroup vg = (ViewGroup) v;
            Utility.setFont(vg);
            continue;
        }
        catch (Exception e) { }
    }
}

Вот как мы это делаем:

private static void OverrideDefaultFont(string defaultFontNameToOverride, string customFontFileNameInAssets, AssetManager assets)
{
    //Load custom Font from File                
    Typeface customFontTypeface = Typeface.CreateFromAsset(assets, customFontFileNameInAssets);

    //Get Fontface.Default Field by reflection
    Class typeFaceClass = Class.ForName("android.graphics.Typeface");
    Field defaultFontTypefaceField = typeFaceClass.GetField(defaultFontNameToOverride);

    defaultFontTypefaceField.Accessible = true;
    defaultFontTypefaceField.Set(null, customFontTypeface);
}

Попробуйте эту библиотеку, ее легкий и простой в использовании

https://github.com/sunnag7/FontStyler

<com.sunnag.fontstyler.FontStylerView
              android:textStyle="bold"
              android:text="@string/about_us"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:paddingTop="8dp"
              app:fontName="Lato-Bold"
              android:textSize="18sp"
              android:id="@+id/textView64" />

Ответ - нет, вы не можете. См. Можно ли установить собственный шрифт для всего приложения? для дополнительной информации.

Есть обходные пути, но ничего в строках "одной строки кода здесь, и все мои шрифты будут такими вместо этого ".

(Я как бы благодарю Google и Apple за это). У пользовательских шрифтов есть место, но если их легко заменить во всем приложении, это создаст целый мир приложений Comic Sans)

Другие вопросы по тегам