Как установить семейство шрифтов по умолчанию для всего 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>
Ответы
Ответ 1
Ответ - да.
Глобальный свет Roboto для классов 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, но это был вопрос. Для пользовательских шрифтов (например, загруженных из активов) этот метод не будет работать.
РЕДАКТИРОВАТЬ 08/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
должен содержать его.
Ответ 2
С выпуском Android Oreo вы можете использовать библиотеку поддержки для достижения этой цели.
- Зайдите в свое приложение build.gradle, если у вас есть библиотека поддержки > =
26.0.0
- Добавьте папку font в папку ресурсов и добавьте туда свои шрифты.
-
Ссылка на семейство шрифтов по умолчанию в главном стиле приложения:
<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.
Ответ 3
Вы можете использовать каллиграфию для управления шрифтами с Android
https://github.com/chrisjenx/Calligraphy
Ответ 4
ПРОЧИТАЙТЕ ОБНОВЛЕНИЕ НИЖЕ
У меня была такая же проблема с встраиванием нового шрифта и, наконец, я получил его для работы с расширением 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. Проверьте это сообщение SO
ОБНОВЛЕНИЕ 2
Начиная с уровня API 26 и доступного в "библиотеке поддержки", вы можете использовать
android:fontFamily="@font/embeddedfont"
Дополнительная информация: Шрифты в XML
Ответ 5
Не говорите о производительности, для пользовательского шрифта вы можете иметь рекурсивный метод цикла через все представления и устанавливать шрифт, если он 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);
Для фрагмента вы можете сделать что-то подобное.
Ответ 6
Другой способ сделать это для всего приложения - использовать отражение, основанное на этом answer
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 и выше для более ранних версий. Проверьте полный пример
Ответ 7
Просто используйте эту библиотеку lib в своем файле сокетов
complie'me.anwarshahriar:calligrapher:1.0'
и использовать его в методе onCreate в основном действии
Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "yourCustomFontHere.ttf", true);
Это самый элегантный супер быстрый способ сделать это.
Ответ 8
Android не обеспечивает многого для поддержки применения шрифтов во всем приложении (см. issue). У вас есть 4 варианта установки шрифта для всего приложения:
- Option1: применить отражение для изменения системного шрифта
- Option2: создавать и подклассы пользовательских классов View для каждого представления, для которого требуется собственный шрифт
- Вариант 3: Внедрение искателя просмотра, который пересекает представление
иерархия для текущего экрана
- Option4: используйте стороннюю библиотеку.
Подробности этих параметров можно найти здесь.
Ответ 9
Я знаю, что этот вопрос довольно старый, но я нашел хорошее решение.
В основном, вы передаете макет контейнера этой функции, и он применит шрифт ко всем поддерживаемым представлениям и рекурсивно зацилит в дочерних макетах:
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) { }
}
}
Ответ 10
просто установить шрифт приложения в 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
Ответ 11
Попробуйте эту библиотеку, ее легкий и простой в использовании
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" />
Ответ 12
Ответ - нет, вы не можете.
См. Можно ли установить собственный шрифт для всего приложения?
Чтобы получить больше информации.
Существуют обходные пути, но ничто в строках "одной единственной строки кода здесь и всех моих шрифтов не будет".
(Я благодарю Google - и Apple - за это). У пользовательских шрифтов есть место, но упрощая их замену на приложение, создало бы целый мир Comic Sans)