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

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

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

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

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

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

 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" , а затем настроить стиль, чтобы заставить это приложение шрифтового шрифта широко:

      

API 21 Android 5.0

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

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

  

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

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

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

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

а затем создайте class, который расширяет 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() ); } } 

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

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

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

  

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

Хотя это не будет работать для целого приложения, оно будет работать для Activity и может быть повторно использовано для любого другого Activity. Я обновил свой код благодаря @ FR073N для поддержки других представлений. Я не уверен в проблемах с Buttons , RadioGroups и т. Д., Потому что эти classы расширяют 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); 

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

В итоге:

Вариант №1: Используйте reflection для применения шрифта (сочетая ответ 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 newMap = new HashMap(); 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(); } } } } 

Использование в classе приложений:

 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-леденец:

      

Lollipop (API 21):

       

Вариант 2: Подclass каждый Просмотр, где вам нужно настроить шрифт, т. Е. 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, так как он сэкономил много головных болей.

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

причина

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

  

Что касается шрифта Roboto Regular по умолчанию:

 sans-serif 

В исходном ответе не применяется monoширинный шрифт, так как 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 newMap = new HashMap(); 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. Загрузите и поместите ур пользовательский шрифт в свойствах. Затем напишите один отдельный class для текстового представления следующим образом: здесь я использовал шрифт 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:

   

Я бы также предложил расширить 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

      

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

       

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

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

ZTE V5 (android 5.1 CM12.1)

Заметка XIAOMI (android 4.4 MIUI6)

HUAWEI C8850 (android 2.3.5 UNKNOWN)

Блестящее решение можно найти здесь: 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 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 typefaces) { if (Build.VERSION.SDK_INT == 21) { try { final Field field = Typeface.class.getDeclaredField("sSystemFontMap"); field.setAccessible(true); Map oldFonts = (Map) 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 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); } } 

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

  new FontsOverride(this).loadFonts(); 

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

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

Работа для 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"); } } } 

Стиль:

  

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

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

TL; DR:

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

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

      

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

   

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

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

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

  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 в описанный выше метод шрифта. например, ваш макет:

         

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

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

Решение 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.

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

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

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

 typefaceAssigner.assignTypeface(view); 

в api 26 с build.gradle 3.0.0 и выше вы можете создать каталог шрифтов в res и использовать эту строку в своем стиле

 @font/your_font 

для change build.gradle используйте это в ваших застройках build.gradle

 classpath 'com.android.tools.build:gradle:3.0.0' 

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

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

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

  

и в classе 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 с прописным и полужирным шрифтом:

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

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

Во-первых, вам нужно обновить поддержку библиотеки 26+ (вам также может потребоваться обновить вашу студию gradle {4.0+}, android studio), затем вы можете создать новую папку ресурсов, называемую шрифтом. В этой папке вы можете разместить свои ресурсы шрифта (.tff, …). Затем вам нужно переопределить приложение по умолчанию и добавить в него свой собственный шрифт 🙂

  

Примечание. Если вы хотите поддерживать устройства со старым API, чем 16, вы должны использовать пространство имен приложений вместо android!

Для изменения семейства шрифтов по умолчанию в TextViews переопределите textViewStyle в теме приложения.

For using custom font in fontFamily, use font resources which is in support library.

The feature was added in Android 26 but backported to older versions via supportlib.

https://developer.android.com/guide/topics/resources/font-resource.html https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#using-support-lib

Since the release of Android Oreo and its support library (26.0.0) you can do this easily. Refer to this answer in another question.

Basically your final style will look like this:

  

Yes, its possible to set the font to the entire application.

The easiest way to accomplish this is to package the desired font(s) with your application.

To do this, simply create an assets/ folder in the project root, and put your fonts (in TrueType, or TTF, form) in the assets.

You might, for example, create assets/fonts/ and put your TTF files in there.

 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); } } 
  • Android: переключение камеры при нажатии кнопки
  • Почему double width = 50/110000; выход составляет 0,000000000000000?
  • Android: почему setVisibility (View.GONE); или setVisibility (View.INVISIBLE); не работает
  • libavcodec.so: имеет перемещение текста
  • Разрешения Android M: onRequestPermissionsResult () не вызывается
  • ПРЕДУПРЕЖДЕНИЕ: невозможно изменить разрешения для всех:
  • Android Как нарисовать гладкую линию после пальца
  • java.lang.ClassNotFoundException: Не нашел class на пути: dexpathlist
  • Регистрация кнопки гарнитуры с помощью BroadcastReceiver на Android
  • Как Java реализует объединение строк?
  • Запуск Google Maps Directions через намерение Android
  • Давайте будем гением компьютера.