Intereting Posts
Android – «Экспортированный приемник не требует разрешения» на приемниках, предназначенных для получения от системных служб Каковы различия между FLAG_ACTIVITY_RESET_TASK_IF_NEEDED и FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP? Как узнать, вызвана ли операция с помощью startActivityForResult или просто вызвана с помощью startActivity? MenuItemCompat.getActionView всегда возвращает null КоординаторLayout не заходит за строку состояния даже с окномTranslucentStatus и fitsSystemWindows Android – SupportMapFragment с API GoogleMaps 2.0, предоставляющий IllegalArgumentException Эмулятор не отображается в adb-устройствах Предупреждение о безопасности на libdvm.so отмечено при развертывании приложений для Android Как воспроизводить видео в android из папки с ресурсами или в необработанной папке? Android-переключатель widget textOn и textOff не работают в Lollipop Как я могу разместить макет прямо над экранной клавиатурой Android? Квадратный модифицированный сервер макет для тестирования Когда вы вызываете initLoader во Фрагменте? Как программно заблокировать экран в Android? Поделитесь текстом через Intent на Facebook без использования Facebook sdk

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

Мне нужно использовать определенный шрифт для всего моего приложения. У меня есть файл .ttf для него. Можно ли установить это как шрифт по умолчанию, при запуске приложения, а затем использовать его в другом месте приложения? Когда он установлен, как его использовать в моих XML-макетах?

Solutions Collecting From Web of "Можно ли настроить собственный шрифт для всего приложения?"

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

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

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> 

Хотя это не будет работать для целого приложения, оно будет работать для Activity и может быть повторно использовано для любого другого Activity. Я обновил свой код благодаря @ FR073N для поддержки других представлений. Я не уверен в проблемах с Buttons , RadioGroups и т. Д., Потому что эти классы расширяют TextView поэтому они должны работать нормально. Я добавил логическое условие для использования отражения, потому что оно кажется очень хакерским и может значительно ухудшить производительность.

Примечание: как указано, это не будет работать для динамического контента! Для этого можно вызвать этот метод с помощью onCreateView или getView , но требует дополнительных усилий.

 /** * Recursively sets a {@link Typeface} to all * {@link TextView}s in a {@link ViewGroup}. */ public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect) { if (mContainer == null || mFont == null) return; final int mCount = mContainer.getChildCount(); // Loop through all of the children. for (int i = 0; i < mCount; ++i) { final View mChild = mContainer.getChildAt(i); if (mChild instanceof TextView) { // Set the font if it is a TextView. ((TextView) mChild).setTypeface(mFont); } else if (mChild instanceof ViewGroup) { // Recursively attempt another ViewGroup. setAppFont((ViewGroup) mChild, mFont); } else if (reflect) { try { Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class); mSetTypeface.invoke(mChild, mFont); } catch (Exception e) { /* Do something... */ } } } } 

Затем, чтобы использовать его, вы сделали бы что-то вроде этого:

 final Typeface mFont = Typeface.createFromAsset(getAssets(), "fonts/MyFont.ttf"); final ViewGroup mContainer = (ViewGroup) findViewById( android.R.id.content).getRootView(); HomeActivity.setAppFont(mContainer, mFont); 

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

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

Вот пример того, как его использовать.

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

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

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

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

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

И он изменит всю деятельность на ваш шрифт! Это просто и чисто!

Я хотел бы улучшить ответ Weston для API 21 Android 5.0.

причина

В API 21 большинство стилей текста включают в себя настройку fontFamily, например:

 <style name="TextAppearance.Material"> <item name="fontFamily">@string/font_family_body_1_material</item> </style> 

Который применяет шрифт Roboto Regular по умолчанию:

 <string name="font_family_body_1_material">sans-serif</string> 

В исходном ответе не применяется моноширинный шрифт, так как android: fontFamily имеет больший приоритет для атрибута android: typeface ( reference ). Использование Theme.Holo. * Является допустимым обходным решением, потому что внутри него нет настроек android: fontFamily.

Решение

Поскольку Android 5.0 помещает системный шрифт в статическую переменную Typeface.sSystemFontMap ( reference ), мы можем использовать ту же технику отражения, что и для ее замены:

 protected static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) { if (isVersionGreaterOrEqualToLollipop()) { Map<String, Typeface> newMap = new HashMap<String, Typeface>(); newMap.put("sans-serif", newTypeface); 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 staticField = Typeface.class .getDeclaredField(staticTypefaceFieldName); staticField.setAccessible(true); staticField.set(null, newTypeface); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } 

В итоге:

Вариант №1: Используйте отражение для применения шрифта (сочетая ответ Weston & Roger Huang ):

 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) { if (isVersionGreaterOrEqualToLollipop()) { Map<String, Typeface> newMap = new HashMap<String, Typeface>(); newMap.put("sans-serif", newTypeface); 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 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"); } } 

Настроить стиль, чтобы заставить это приложение шрифтового шрифта широко (на основе lovefish ):

Pre-леденец:

 <resources> <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <item name="android:typeface">monospace</item> </style> </resources> 

Lollipop (API 21):

 <resources> <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <item name="android:textAppearance">@style/CustomTextAppearance</item> </style> <style name="CustomTextAppearance"> <item name="android:typeface">monospace</item> </style> </resources> 

Вариант 2: Подкласс каждый Просмотр, где вам нужно настроить шрифт, т. Е. ListView, EditTextView, Button и т. Д. (Ответ Палани ):

 public class CustomFontView extends TextView { public CustomFontView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public CustomFontView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomFontView(Context context) { super(context); init(); } private void init() { if (!isInEditMode()) { Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf"); setTypeface(tf); } } 

Вариант 3. Внедрение искателя просмотра, проходящего через иерархию представления текущего экрана:

Вариант №1 (ответ Том ):

 public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect) { if (mContainer == null || mFont == null) return; final int mCount = mContainer.getChildCount(); // Loop through all of the children. for (int i = 0; i < mCount; ++i) { final View mChild = mContainer.getChildAt(i); if (mChild instanceof TextView) { // Set the font if it is a TextView. ((TextView) mChild).setTypeface(mFont); } else if (mChild instanceof ViewGroup) { // Recursively attempt another ViewGroup. setAppFont((ViewGroup) mChild, mFont); } else if (reflect) { try { Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class); mSetTypeface.invoke(mChild, mFont); } catch (Exception e) { /* Do something... */ } } } } 

Применение :

 final ViewGroup mContainer = (ViewGroup) findViewById( android.R.id.content).getRootView(); HomeActivity.setAppFont(mContainer, Typeface.createFromAsset(getAssets(), "fonts/MyFont.ttf")); 

Вариант №2: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere .

Вариант № 4: используйте стороннюю Lib, называемую каллиграфией .

Лично я бы порекомендовал вариант № 4, так как он сэкономил много головных болей.

Его очень просто … 1. Загрузите и поместите урский шрифт в активы. Затем напишите один отдельный класс для текстового представления следующим образом: здесь я использовал шрифт futura

 public class CusFntTextView extends TextView { public CusFntTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public CusFntTextView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CusFntTextView(Context context) { super(context); init(); } private void init() { if (!isInEditMode()) { Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf"); setTypeface(tf); } } 

}

И выполните следующие действия в xml:

  <com.packagename.CusFntTextView android:id="@+id/tvtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hi Android" android:textAppearance="?android:attr/textAppearanceLarge" /> 

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

 public FontTextView(Context context) { super(context); init(); } public FontTextView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public FontTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } protected void init() { setTypeface(Typeface.createFromAsset(getContext().getAssets(), AppConst.FONT)); } 

Я хотел бы улучшить ответы Weston и Roger Huang для более ледипопа API 21 Android с темой « Theme.AppCompat ».

Ниже Android 4.4

 <resources> <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <item name="android:typeface">monospace</item> </style> </resources> 

Более (равный) API 5.0

 <resources> <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <item name="android:textAppearance">@style/CustomTextAppearance</item> </style> <style name="CustomTextAppearance"> <item name="android:typeface">monospace</item> </style> </resources> 

И файл FontsOverride util такой же, как и в ответе Weston . Я тестировал эти телефоны:

Nexus 5 (Android-система Android 5.1)

ZTE V5 (android 5.1 CM12.1)

Заметка XIAOMI (андроид 4.4 MIUI6)

HUAWEI C8850 (android 2.3.5 UNKNOWN)

Работа для Xamarin.Android:

Класс:

 public class FontsOverride { public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName) { Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName); ReplaceFont(staticTypefaceFieldName, regular); } protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface) { try { Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName); staticField.Accessible = true; staticField.Set(null, newTypeface); } catch (Exception e) { Console.WriteLine(e.Message); } } } 

Применение:

 namespace SomeAndroidApplication { [Application] public class App : Application { public App() { } public App(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { } public override void OnCreate() { base.OnCreate(); FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf"); } } } 

Стиль:

 <style name="Theme.Storehouse" parent="Theme.Sherlock"> <item name="android:typeface">monospace</item> </style> 

Блестящее решение можно найти здесь: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere .

Просто расширьте действия из BaseActivity и напишите эти методы. Также вы должны лучше кэшировать шрифты, как описано здесь: https://stackoverflow.com/a/16902532/2914140 .


После некоторых исследований я написал код, который работает в Samsung Galaxy Tab A (Android 5.0). Используемый код Weston и Roger Huang, а также https://stackoverflow.com/a/33236102/2914140 . Также тестируется на Lenovo TAB 2 A10-70L, где он не работает. Здесь я добавил шрифт Comic Sans, чтобы увидеть разницу.

 import android.content.Context; import android.graphics.Typeface; import android.os.Build; import android.util.Log; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class FontsOverride { private static final int BOLD = 1; private static final int BOLD_ITALIC = 2; private static final int ITALIC = 3; private static final int LIGHT = 4; private static final int CONDENSED = 5; private static final int THIN = 6; private static final int MEDIUM = 7; private static final int REGULAR = 8; private Context context; public FontsOverride(Context context) { this.context = context; } public void loadFonts() { Map<String, Typeface> fontsMap = new HashMap<>(); fontsMap.put("sans-serif", getTypeface("comic.ttf", REGULAR)); fontsMap.put("sans-serif-bold", getTypeface("comic.ttf", BOLD)); fontsMap.put("sans-serif-italic", getTypeface("comic.ttf", ITALIC)); fontsMap.put("sans-serif-light", getTypeface("comic.ttf", LIGHT)); fontsMap.put("sans-serif-condensed", getTypeface("comic.ttf", CONDENSED)); fontsMap.put("sans-serif-thin", getTypeface("comic.ttf", THIN)); fontsMap.put("sans-serif-medium", getTypeface("comic.ttf", MEDIUM)); overrideFonts(fontsMap); } private void overrideFonts(Map<String, Typeface> typefaces) { if (Build.VERSION.SDK_INT == 21) { 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", "Cannot set custom fonts"); } } else { try { for (Map.Entry<String, Typeface> entry : typefaces.entrySet()) { final Field staticField = Typeface.class.getDeclaredField(entry.getKey()); staticField.setAccessible(true); staticField.set(null, entry.getValue()); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } private Typeface getTypeface(String fontFileName, int fontType) { final Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontFileName); return Typeface.create(tf, fontType); } } 

Чтобы запустить код во всем приложении, вы должны написать в каком-то классе, например Application, следующее:

  new FontsOverride(this).loadFonts(); 

Создайте папку «шрифты» внутри «активов» и разместите необходимые шрифты. Простую инструкцию можно найти здесь: https://stackoverflow.com/a/31697103/2914140 .

Устройство Lenovo также неправильно получает значение шрифта. В большинстве случаев он возвращает Typeface.NORMAL, иногда null. Даже если TextView выделен жирным шрифтом (в макете xml-файла). См. Здесь: TextView isBold всегда возвращает NORMAL . Таким образом, текст на экране всегда имеет регулярный шрифт, а не полужирный или курсив. Поэтому я думаю, что это ошибка производителя.

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

  public class Font { private static Font font; public Typeface ROBO_LIGHT; private Font() { } public static Font getInstance(Context context) { if (font == null) { font = new Font(); font.init(context); } return font; } public void init(Context context) { ROBO_LIGHT = Typeface.createFromAsset(context.getAssets(), "Roboto-Light.ttf"); } } 

Вы можете определить разные шрифты в указанном выше классе. Теперь определите класс Helper-шрифта, который будет применять шрифты:

  public class FontHelper { private static Font font; public static void applyFont(View parentView, Context context) { font = Font.getInstance(context); apply((ViewGroup)parentView); } private static void apply(ViewGroup parentView) { for (int i = 0; i < parentView.getChildCount(); i++) { View view = parentView.getChildAt(i); //You can add any view element here on which you want to apply font if (view instanceof EditText) { ((EditText) view).setTypeface(font.ROBO_LIGHT); } if (view instanceof TextView) { ((TextView) view).setTypeface(font.ROBO_LIGHT); } else if (view instanceof ViewGroup && ((ViewGroup) view).getChildCount() > 0) { apply((ViewGroup) view); } } } } 

В приведенном выше коде я использую шрифты только для textView и EditText, вы также можете применять шрифты к другим элементам представления. Вам просто нужно передать идентификатор вашей корневой группы View указанному выше методу шрифта. Например, ваш макет:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/mainParent" tools:context="${relativePackage}.${activityClass}" > <RelativeLayout android:id="@+id/mainContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/homeFooter" android:layout_below="@+id/edit" > <ImageView android:id="@+id/PreviewImg" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/abc_list_longpressed_holo" android:visibility="gone" /> <RelativeLayout android:id="@+id/visibilityLayer" android:layout_width="match_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/UseCamera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:src="@drawable/camera" /> <TextView android:id="@+id/tvOR" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/UseCamera" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:text="OR" android:textSize="30dp" /> <TextView android:id="@+id/tvAND" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:text="OR" android:textSize="30dp" /> </RelativeLayout> 

В верхней макете корневой родительский идентификатор «Основной родитель» теперь позволяет применять шрифт

 public class MainActivity extends BaseFragmentActivity { private EditText etName; private EditText etPassword; private TextView tvTitle; public static boolean isHome = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Font font=Font.getInstance(getApplicationContext()); FontHelper.applyFont(findViewById(R.id.mainParent), getApplicationContext()); } } 

Приветствия 🙂

Я бы предложил расширить TextView и всегда использовать свой собственный TextView в ваших XML-макетах или везде, где вам нужен TextView. В пользовательском TextView переопределите setTypeface

 @Override public void setTypeface(Typeface tf, int style) { //to handle bold, you could also handle italic or other styles here as well if (style == 1){ tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans700.otf"); }else{ tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans500.otf"); } super.setTypeface(tf, 0); } 

Начиная с Android O, теперь можно определить непосредственно из XML, и моя ошибка теперь закрыта!

Подробнее см. Здесь

TL; DR:

Сначала вы должны добавить свои шрифты в проект

Во-вторых, вы добавляете семейство шрифтов, например:

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

Наконец, вы можете использовать шрифт в макете или стиле:

 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/lobster"/> <style name="customfontstyle" parent="@android:style/TextAppearance.Small"> <item name="android:fontFamily">@font/lobster</item> </style> 

Наслаждайтесь!

Решение Tom отлично работает, но работает только с TextView и EditText.

Если вы хотите охватить большинство просмотров (RadioGroup, TextView, Checkbox …), я создал метод, который делает это:

 protected void changeChildrenFont(ViewGroup v, Typeface font){ for(int i = 0; i < v.getChildCount(); i++){ // For the ViewGroup, we'll have to use recursivity if(v.getChildAt(i) instanceof ViewGroup){ changeChildrenFont((ViewGroup) v.getChildAt(i), font); } else{ try { Object[] nullArgs = null; //Test wether setTypeface and getTypeface methods exists Method methodTypeFace = v.getChildAt(i).getClass().getMethod("setTypeface", new Class[] {Typeface.class, Integer.TYPE}); //With getTypefaca we'll get back the style (Bold, Italic...) set in XML Method methodGetTypeFace = v.getChildAt(i).getClass().getMethod("getTypeface", new Class[] {}); Typeface typeFace = ((Typeface)methodGetTypeFace.invoke(v.getChildAt(i), nullArgs)); //Invoke the method and apply the new font with the defined style to the view if the method exists (textview,...) methodTypeFace.invoke(v.getChildAt(i), new Object[] {font, typeFace == null ? 0 : typeFace.getStyle()}); } //Will catch the view with no such methods (listview...) catch (Exception e) { e.printStackTrace(); } } } } 

Этот метод вернет стиль представления, заданного в XML (жирный, курсив …) и применит их, если они существуют.

Для ListView я всегда создаю адаптер, и я устанавливаю шрифт внутри getView.

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

 public final class TypefaceAssigner { public final Typeface DEFAULT; public final Typeface DEFAULT_BOLD; @Inject public TypefaceAssigner(AssetManager assetManager) { DEFAULT = Typeface.createFromAsset(assetManager, "TradeGothicLTCom.ttf"); DEFAULT_BOLD = Typeface.createFromAsset(assetManager, "TradeGothicLTCom-Bd2.ttf"); } public void assignTypeface(View v) { if (v instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) { View view = ((ViewGroup) v).getChildAt(i); if (view instanceof ViewGroup) { setTypeface(view); } else { setTypeface(view); } } } else { setTypeface(v); } } private void setTypeface(View view) { if (view instanceof TextView) { TextView textView = (TextView) view; Typeface typeface = textView.getTypeface(); if (typeface != null && typeface.isBold()) { textView.setTypeface(DEFAULT_BOLD); } else { textView.setTypeface(DEFAULT); } } } } по public final class TypefaceAssigner { public final Typeface DEFAULT; public final Typeface DEFAULT_BOLD; @Inject public TypefaceAssigner(AssetManager assetManager) { DEFAULT = Typeface.createFromAsset(assetManager, "TradeGothicLTCom.ttf"); DEFAULT_BOLD = Typeface.createFromAsset(assetManager, "TradeGothicLTCom-Bd2.ttf"); } public void assignTypeface(View v) { if (v instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) { View view = ((ViewGroup) v).getChildAt(i); if (view instanceof ViewGroup) { setTypeface(view); } else { setTypeface(view); } } } else { setTypeface(v); } } private void setTypeface(View view) { if (view instanceof TextView) { TextView textView = (TextView) view; Typeface typeface = textView.getTypeface(); if (typeface != null && typeface.isBold()) { textView.setTypeface(DEFAULT_BOLD); } else { textView.setTypeface(DEFAULT); } } } } 

Теперь во всех фрагментах inViewCreated или onCreateView во всех действиях в onCreate и во всех представлениях адаптеры в getView или newView просто вызывают:

 typefaceAssigner.assignTypeface(view); 

Я также хотел бы улучшить ответ Weston для API 21 Android 5.0.

У меня была такая же проблема на моем Samsung s5 при использовании шрифта DEFAULT. (С другими шрифтами он работает нормально)

Мне удалось заставить его работать, установив шрифт (например, «sans») в XML-файлах, для каждого Textview или Button

 <TextView android:layout_width="match_parent" android:layout_height="39dp" android:textColor="@color/abs__background_holo_light" android:textSize="12sp" android:gravity="bottom|center" android:typeface="sans" /> 

И в классе MyApplication:

 public class MyApplication extends Application { @Override public void onCreate() { TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF", "fonts/my_font.ttf"); } } 

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

Это решение работает некорректно в некоторых ситуациях.
Поэтому я продлеваю его:

FontsReplacer.java

 public class MyApplication extends Application { @Override public void onCreate() { FontsReplacer.replaceFonts(this); super.onCreate(); } } 

https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805

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

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

Чтобы использовать Fontain, вы должны добавить следующее в свой модуль приложения build.gradle:

 compile 'com.scopely:fontain:1.0.0' 

Затем вместо обычного TextView вы должны использовать FontTextView

Пример FontTextView с прописным и полужирным шрифтом:

  <com.scopely.fontain.views.FontTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/black" android:textColor="@android:color/white" android:textSize="11dp" android:gravity="center" android:id="@+id/tv1" app:font_family="myCustomFont" app:caps_mode="characters" app:font_weight="BOLD"/> 
 package com.theeasylearn.demo.designdemo; import android.content.Context; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.TextView; public class MyButton extends TextView { public MyButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public MyButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyButton(Context context) { super(context); init(); } private void init() { Typeface tf = Typeface.createFromAsset( getContext().getAssets(), "angelina.TTF"); setTypeface(tf); } } 

Да, возможно установить шрифт для всего приложения.

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

Для этого просто создайте активы / папку в корне проекта и поместите в свои объекты шрифты (в форме TrueType или TTF).

Например, вы можете создавать активы / шрифты / и размещать там TTF-файлы.

 public class FontSampler extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); TextView tv=(TextView)findViewById(R.id.custom); Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf"); tv.setTypeface(face); } }