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


Я использую шрифт Roboto light в своем приложении. Чтобы установить шрифт, я должен добавить 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>
12 197

12 ответов:

ответ-да.

Global Roboto light for 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>

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

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

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

редактировать 13.08.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. проверьте в вашем приложении построить.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 для получения более подробной информации.

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

обновление 2

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

android:fontFamily="@font/embeddedfont"

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

не говорить о производительности, для пользовательского шрифта вы можете иметь рекурсивный метод цикла через все представления и установить шрифт, если это 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);

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

другой способ сделать это для всего приложения использует отражение на основе этого ответ

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 и выше для более ранних версий проверьте полный пример

просто используйте этот lib скомпилировать его в файле класса

complie'me.anwarshahriar:calligrapher:1.0'

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

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

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

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

  • Option1: применить отражение, чтобы изменить системный шрифт
  • Option2: создание и подкласс пользовательских классов представления для каждого представления, которое нуждается в пользовательском шрифте
  • Option3: реализация искателя Вида, который пересекает вид иерархия для текущего экрана
  • Option4: используйте стороннюю библиотеку.

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

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

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

чтобы просто установить шрифт приложения в 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 file:

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

ссылка на android

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

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 приложения)