Можно ли установить собственный шрифт в приложении для Android?
Я пробовал то, что написано здесь , но не знаю, где находится мой extends Application
класс ...
Любая помощь?
РЕДАКТИРОВАТЬ:
Я пробовал следующее:
- Добавьте папку с ресурсами и вставьте шрифт внутрь, как показано здесь:
Добавьте новый класс, который расширяется от
Application
Назовите этот новый класс из моего
AndroidManifest.xml
.Я подошел к своему стилю и добавил его.
MyApp.java:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
FontsOverride.setDefaultFont(this, "DEFAULT", "raleway_regular.ttf");
// This FontsOverride comes from the example I posted above
}
}
AndroidManifest.xml:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".MyApp"
android:theme="@style/AppTheme">
....
styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">default</item>
</style>
Но мой шрифт все еще не меняется ... есть идеи?
Затем MyApp
вызывается класс. Но на мои шрифты никакого эффекта ...
EDIT2: я понял, что мои кнопки применяют настраиваемый шрифт после того, как я установил собственный стиль для своих кнопок. Вот мой собственный стиль кнопки:
<style name="MyButtonStyle" parent="Widget.AppCompat.Button">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
А вот как это выглядит сейчас:
Итак: моя кнопка применяет стиль, но не TextView
. Есть идеи, почему мой собственный шрифт не применяется ко всем элементам приложения?
источник
Ответы:
Напишите класс
public class MyApp extends Application{ // Put the onCreate code as you obtained from the post link you reffered }
Теперь следующая вещь находится в AndroidManifest.xml для тега приложения, дающего имя для вашего класса приложения. В данном случае это MyApp
<application android:name=".MyApp" ... > ... </application>
Таким образом, всякий раз, когда приложение открывается, будет вызываться метод onCreate класса MyApp, и шрифт будет установлен.
Обновите файл шрифта. Поместите его в папку assets / fonts / your_font_file.ttf.
Поместите эту строку в метод onCreate вашего класса приложения (MyApp)
TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/your_font_file.ttf");
Исходный файл для TypefaceUtil
public class TypefaceUtil { /** * Using reflection to override default typeface * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN * * @param context to work with assets * @param defaultFontNameToOverride for example "monospace" * @param customFontFileNameInAssets file name of the font from assets */ public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) { final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Map<String, Typeface> newMap = new HashMap<String, Typeface>(); newMap.put("serif", customFontTypeface); 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 defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride); defaultFontTypefaceField.setAccessible(true); defaultFontTypefaceField.set(null, customFontTypeface); } catch (Exception e) { Log.e(TypefaceUtil.class.getSimpleName(), "Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride); } } } }
Теперь обновите файл style.xml
поместите строку ниже в свой стиль, который включен для вашей деятельности в файл манифеста
<item name="android:typeface">serif</item>
Надеюсь это поможет
источник
РЕДАКТИРОВАТЬ
uk.co.chrisjenx:calligraphy
Lib больше не поддерживается для последней версии Android, теперь альтернатива https://github.com/InflationX/Calligraphydependencies { implementation 'io.github.inflationx:calligraphy3:3.1.1' implementation 'io.github.inflationx:viewpump:2.0.3' }
Добавьте свои собственные шрифты в активы /
Применение
Для шрифта по умолчанию
Определите шрифт по умолчанию с помощью CalligraphyConfig в своем классе Application в методе #onCreate () и передайте его в CalligraphyInterceptor, который вы добавляете в свой конструктор ViewPump.
@Override public void onCreate() { super.onCreate(); ViewPump.init(ViewPump.builder() .addInterceptor(new CalligraphyInterceptor( new CalligraphyConfig.Builder() .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf") .setFontAttrId(R.attr.fontPath) .build())) .build()); //.... }
Ввести в контекст: обернуть контекст действия:
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase)); }
Пользовательский стиль
<style name="TextViewCustomFont"> <item name="fontPath">fonts/RobotoCondensed-Regular.ttf</item> </style>
Для темы
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> <item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item> </style> <style name="AppTheme.Widget"/> <style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView"> <item name="fontPath">fonts/Roboto-ThinItalic.ttf</item> </style>
Больше не поддерживается разработчиками. Ниже решения
В Android есть отличная библиотека для пользовательских шрифтов: Каллиграфия.
Вот пример ее использования.
В 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() ); } }
Вы должны были создать на assets / «Новый каталог» «шрифты» (см. Ниже), поэтому в этом коде «путь к вашему шрифту» должен быть «fonts / SourceSansPro-Regular.ttf». (Это просто «шрифты ...», а не «/ шрифты ..» или «активы ..»)
И в классе активности поместите этот метод перед onCreate:
@Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); }
И последнее, что ваш файл манифеста должен выглядеть так:
<application . . . android:name=".App">
И это изменит всю активность на ваш шрифт! это просто и чисто!
В Assets вы должны щелкнуть правой кнопкой мыши New Directory, назовите его «fonts». В искателе поместите
.ttf
туда файлы шрифтов.Также не забудьте добавить две строки ниже в attrs.xml, если у вас нет файла attrs.xml, создайте новый файл в values.xml
<attr format="string" name="fontPath"/> <item name="calligraphy_tag_id" type="id"/>
источник
attachBaseContext(..)
он реализован, а затем все классы Activity моего проекта (где мне нужен этот настраиваемый шрифт) расширяют этот базовый классВсе, что я сделал, это:
1: Добавлен «новый каталог ресурсов» в папку RES, выбран ТИП РЕСУРСА как «шрифт» из раскрывающегося списка, назван новый каталог «шрифт» и сохранен.
2: Добавлен мой "custom_font.ttf" в только что созданную папку FONT.
3: Добавлен собственный шрифт в базовую тему приложения в STYLES.XML.
СДЕЛАННЫЙ.
источник
Вы можете сделать это с помощью SDK для Android прямо сейчас, поскольку официальный канал YouTube для разработчиков Android опубликован в set / 2017 здесь .
Требуется уровень API 26 (Android 8 Oreo) и выше.
Вам просто нужно поместить файл шрифта в
res/font
папку и ссылаться на них в вашемTextView
случае, если вам нужен конкретный файл сandroid:fontFamily
атрибутом.Если вам нужен базовый шрифт для всего приложения, просто поместите
<item name="android:fontFamily">@font/yourfontname</item>
в вашем
styles.xml
Вы можете загрузить собственный шрифт из Android Studio и на ходу, если хотите. Все это вы можете найти в видео выше.
источник
Android предоставляет более простые и лучшие решения, которые поддерживаются на уровне API 14 библиотекой поддержки 26+. Шрифты в XML. Он также поддерживает вариант семейства шрифтов . Обязательный импорт:
implementation "com.android.support:support-compat:<26+ version>"
Выполните следующие простые шаги, и семейство шрифтов будет применено в вашем приложении без каких-либо препятствий:
Или используйте ниже, чтобы программно установить шрифт
view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
источник
Похоже, вы используете
android:fontFamily
вместоandroid:typeface
своегоstyles.xml
.Попробуйте заменить
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:fontFamily">default</item> </style>
с участием
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:typeface">default</item> </style>
источник
Application
вы просто создаете подкласс класса вашего приложенияApplication
. Так что подключать его не нужно.<item name="android:typeface">default</item>
строку<style name="AppTheme" parent="AppBaseTheme">
вres -> values -> styles.xml
файл своего приложения, как это предлагается в том же сообщении SO?Если вы следите за первой темой, это должно сработать: Здесь
Да, с отражением. Это работает ( на основе этого ответа ):
(Примечание: это обходной путь из-за отсутствия поддержки пользовательских шрифтов, поэтому, если вы хотите изменить эту ситуацию, нажмите звездочку, чтобы проголосовать за проблему с Android здесь). Примечание. Не оставляйте комментариев «я тоже» по этой проблеме, все, кто ее рассматривал, получат электронное письмо, когда вы это сделаете. Так что просто поставьте звезду, пожалуйста.
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>
источник
res
затем изnew
опции выбратьAndroid Resource Directory
и выбратьfont
формуResource type
и нажать ОК, это создаст каталог шрифтов для размещения в нем ваших шрифтов..ttf
туда свои файлы шрифтов.Перейдите в файл стиля проекта, который существует по следующему пути,
res/values/styles.xml
и добавьте такие стили:<style name="SansSerifFont"> <item name="android:fontFamily">sans-serif</item> </style> <style name="OpenSansFont"> <item name="android:fontFamily">@font/open_sans</item> </style> <style name="IranianSansFont"> <item name="android:fontFamily">@font/iranian_sans</item> </style> <style name="BYekanFont"> <item name="android:fontFamily">@font/b_yekan</item> </style> <style name="DroidArabicFont"> <item name="android:fontFamily">@font/droid_arabic</item> </style>
Перейдите к своему коду и напишите такой класс для изменения шрифта всего приложения:
public class AppFontManager { private AppCompatActivity appCompatActivity; public static final String SANS_SERIF_APP_FONT = "sans_serif"; public static final String B_YEKAN_APP_FONT = "b_yekan"; public static final String DROID_ARABIC_APP_FONT = "droid_arabic"; public static final String IRANIAN_SANS_APP_FONT = "iranian_sans"; public static final String OPEN_SANS_APP_FONT = "open_sans"; public AppAppearanceManager(AppCompatActivity appCompatActivity) { this.appCompatActivity = appCompatActivity; } public void setFont(String fontName){ switch (fontName){ case SANS_SERIF_APP_FONT:{ appCompatActivity.getTheme().applyStyle(R.style.SansSerifFont, true); break; } case B_YEKAN_APP_FONT:{ appCompatActivity.getTheme().applyStyle(R.style.BYekanFont, true); break; } case DROID_ARABIC_APP_FONT:{ appCompatActivity.getTheme().applyStyle(R.style.DroidArabicFont, true); break; } case IRANIAN_SANS_APP_FONT:{ appCompatActivity.getTheme().applyStyle(R.style.IranianSansFont, true); break; } case OPEN_SANS_APP_FONT:{ appCompatActivity.getTheme().applyStyle(R.style.OpenSansFont, true); break; } } } }
Поскольку шрифты должны устанавливаться отдельно для каждого действия, я предпочитаю написать для него класс, чтобы код был более чистым.
Затем вызовите метод класса перед действием onCreate
super.onCreate(savedInstanceState)
:@Override protected void onCreate(Bundle savedInstanceState) { new AppAppearanceManager(this).setFont(APP_DEFAULT_FONT); super.onCreate(savedInstanceState); // Do you stuff there... }
Помните, что если вы хотите изменить шрифт во время выполнения , напишите выбранный шрифт
SharedPreferences
и т. Д., Затем передайте выбранный шрифт всем действиям,setFont
как указано выше.источник
Создайте папку с активами в основной папке. Добавьте в нее папку со шрифтами. добавьте файл .ttf в папку шрифтов.
Добавьте в свою тему приложения следующее:
<item name="android:fontFamily">@font/roboto_regular</item> <item name="fontFamily">@font/roboto_regular</item>
Создать класс как TypefaceUtil
import android.content.Context; import android.graphics.Typeface; import android.util.Log; import java.lang.reflect.Field; public class TypefaceUtil { /** * Using reflection to override default typeface * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN * @param context to work with assets * @param defaultFontNameToOverride for example "monospace" * @param customFontFileNameInAssets file name of the font from assets */ 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) { Log.e("Can not set","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride); } } }
Вызовите его в классе приложения или в действии Launcher
TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
источник
Сначала создайте новый класс, который переопределяет любой вид, который вы хотите настроить. (например, хотите кнопку с настраиваемым шрифтом? Расширить
Button
). Например:public class CustomButton extends Button { private final static int ROBOTO = 0; private final static int ROBOTO_CONDENSED = 1; public CustomButton(Context context) { super(context); } public CustomButton(Context context, AttributeSet attrs) { super(context, attrs); parseAttributes(context, attrs); //I'll explain this method later } public CustomButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); parseAttributes(context, attrs); } }
Теперь, если у вас его нет, добавьте XML-документ
res/values/attrs.xml
и добавьте:<resources> <!-- Define the values for the attribute --> <attr name="typeface" format="enum"> <enum name="roboto" value="0"/> <enum name="robotoCondensed" value="1"/> </attr> <!-- Tell Android that the class "CustomButton" can be styled, and which attributes it supports --> <declare-styleable name="CustomButton"> <attr name="typeface"/> </declare-styleable> </resources>
Итак, разобравшись с этим, давайте вернемся к
parseAttributes()
методу, описанному ранее:private void parseAttributes(Context context, AttributeSet attrs) { TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton); //The value 0 is a default, but shouldn't ever be used since the attr is an enum int typeface = values.getInt(R.styleable.CustomButton_typeface, 0); switch(typeface) { case ROBOTO: default: //You can instantiate your typeface anywhere, I would suggest as a //singleton somewhere to avoid unnecessary copies setTypeface(roboto); break; case ROBOTO_CONDENSED: setTypeface(robotoCondensed); break; } values.recycle(); }
Теперь все готово. Вы можете добавить дополнительные атрибуты для чего угодно (вы можете добавить еще один для typefaceStyle - жирный, курсив и т. Д.), Но теперь давайте посмотрим, как его использовать:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.yourpackage.name.CustomButton android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me!" custom:typeface="roboto" /> </LinearLayout>
xmlns:custom
Линия действительно может быть что угодно, но соглашение является то , что показано выше. Важно то, что он уникален, и поэтому используется имя пакета. Теперь вы просто используетеcustom:
префикс для своих атрибутов иandroid:
префикс для атрибутов Android.И последнее: если вы хотите использовать это в style (
res/values/styles.xml
), вам не следует добавлятьxmlns:custom
строку. Просто укажите имя атрибута без префикса:<style name="MyStyle> <item name="typeface">roboto</item> </style>
источник
Я тоже пробовал переопределить шрифт, но, в конце концов, это не надежное решение, к сожалению, переопределение шрифтов требует большего. Вы можете дождаться выхода Android O с настраиваемым шрифтом или использовать стороннюю библиотеку.
Последним решением, с которым я столкнулся, была эта библиотека Caligraphy , которую было легко запустить и которая позволяла использовать столько шрифтов, сколько захотите. Проверяя его исходный код, я понял, почему просто переопределение шрифтов не сработает, поэтому, даже если вы не планируете его использовать, я рекомендую прочитать его один раз ..
Удачи
источник
Попробуйте код ниже, он работает для меня, надеюсь, он вам тоже поможет.
public class BaseActivity extends AppCompatActivity { private Typeface typeace; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); typeace = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name)); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); overrideFonts(this,getWindow().getDecorView()); } private void overrideFonts(final Context context, final View v) { try { if (v instanceof ViewGroup) { ViewGroup vg = (ViewGroup) v; for (int i = 0; i < vg.getChildCount(); i++) { View child = vg.getChildAt(i); overrideFonts(context, child); } } else if (v instanceof TextView) { ((TextView) v).setTypeface(typeace); } else if (v instanceof EditText ) { ((EditText) v).setTypeface(typeace); } else if (v instanceof Button) { ((Button) v).setTypeface(typeace); } } catch (Exception e) { } } }
Теперь распространите эту BaseActivity на любую из ваших Activity, или вы можете создать тот же класс для фрагмента, если используете.
Примечание: - Если вы хотите установить для некоторых видов другой шрифт, вы должны установить это программно, как показано ниже.
private Typeface typeface; typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold)); tvUserName.setTypeface(typeface);
Так что попробуйте и дайте мне знать, если бы я мог вам помочь
источник
Обходом для котлина будет это
Суть решения https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7
Шаг первый
Поместите файл шрифта в assets / fonts / your_font_file.ttf и создайте класс kotlin с именем TypeFaceUtil.
class TypefaceUtil{ fun overridefonts(context: Context, defaultFontToOverride:String, customFontFileNameInAssets:String){ try { val customTypeface = Typeface.createFromAsset(context.assets,customFontFileNameInAssets) val defaultTypefaceField = Typeface::class.java.getDeclaredField(defaultFontToOverride) defaultTypefaceField.isAccessible = true defaultTypefaceField.set(null,customTypeface) }catch (e:Exception){ Timber.e("Cannot set font $customFontFileNameInAssets instead of $defaultFontToOverride") } } }
Шаг второй Затем в вашем
onCreate
val typefaceUtil = TypefaceUtil() typefaceUtil.overridefonts(this,"SERIF","fonts/font_file.ttf")
Шаг третий
добавьте это в свой стиль
<item name="android:typeface">serif</item>
источник
Названия шрифтов должны быть в нижнем регистре, чтобы они отображались в приложении и работали.
источник