Как настроить пользовательский шрифт для всего приложения на Android?
Можно ли установить пользовательский шрифт в приложении Android?
Я пробовал то, что размещено здесь, но я не знаю, где мой класс extends Application
...
Любая помощь?
EDIT:
Я попробовал следующее:
- Добавьте папку с ресурсами и вставьте шрифт внутри, как показано здесь:
![введите описание изображения здесь]()
-
Добавьте новый класс, который простирается от 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
. Любая идея о том, почему мой пользовательский шрифт не применяется ко всем элементам приложения?
Ответы
Ответ 1
Напишите класс
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, и шрифт будет установлен.
Обновление
Поместите файл шрифта под активы /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>
Надеюсь, что это поможет
Ответ 2
В 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/a "New Directory" "шрифты" (см. Ниже), поэтому в этом коде "ваш путь шрифта" должен быть "fonts/SourceSansPro-Regular.ttf". (Это просто "шрифты...", а не "/шрифты.." или "активы..")
И в классе активности поместите этот метод перед onCreate:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
И последнее, что ваш файл манифеста должен выглядеть следующим образом:
<application
.
.
.
android:name=".App">
И это изменит всю активность на ваш шрифт! это просто и чисто!
На Активах вы должны щелкнуть правой кнопкой мыши Новый каталог, назовите его "шрифты". В поисковике поместите туда файлы шрифтов .ttf
.
![enter image description here]()
Также не забудьте добавить ниже две строки в attrs.xml, если у вас нет файла attrs.xml, создайте новый файл в values.xml
<attr format="string" name="fontPath"/>
<item name="calligraphy_tag_id" type="id"/>
Ответ 3
Все, что я сделал, было:
1: Добавлен "новый каталог ресурсов" в папку RES, выбранный ТИП РЕСУРСА как "шрифт" из выпадающего списка, назван новый каталог "шрифт" и сохранен. ![NEW RESOURCE DIRECTORY]()
2: Добавлен мой "custom_font.ttf" в только что созданную папку FONT.
3: Добавлен мой собственный шрифт в базовую тему приложения в STYLES.XML
![STYLES.XML]()
СДЕЛАННЫЙ.
Ответ 4
Вы можете сделать это с помощью Android SDK прямо сейчас, так как официальный канал Android Developer на YouTube опубликован здесь/2017 здесь.
Требуется API уровня 26 (Android 8 Oreo) и выше.
Вам просто нужно поместить файл res/font
папку res/font
и ссылаться на него в вашем TextView
на тот случай, если вам нужен конкретный android:fontFamily
атрибутом android:fontFamily
.
Если вы хотите использовать базовый шрифт для всего приложения, просто
<item name="android:fontFamily">@font/yourfontname</item>
в вашем styles.xml
Вы можете скачать собственный шрифт из Android Studio и на ходу, если хотите. Все это вы можете найти в деталях на видео выше.
Ответ 5
Android предоставляет более простые и лучшие решения, которые поддерживаются через API уровня 14 библиотекой поддержки 26+. Шрифты в XML Также поддерживается опция семейства шрифтов.
Требуется импорт:
implementation "com.android.support:support-compat:<26+ version>"
Выполните следующие простые шаги, и семейство шрифтов будет применено в вашем приложении без каких-либо препятствий:
- Создайте шрифт каталог внутри res
- Вставьте файл шрифтов в шрифт
- Щелкните правой кнопкой мыши папку шрифтов и выберите "Создать"> "Файл ресурсов шрифта". Откроется окно "Новый файл ресурсов".
- Добавить следующие атрибуты
<?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>
- В приведенном выше XML файле. Используйте приложение только для использования библиотеки поддержки. В противном случае вы можете использовать android, если ваше приложение нацелено на уровень API 26+.
- Теперь перейдите в ваш файл styles.xml и поместите нижнюю строку в свой основной стиль.
<item name="android:fontFamily">@font/opensans</item>
- Важное замечание. Используйте AppCompatActivity, только если вы используете библиотеку поддержки.
Или используйте ниже, чтобы установить гарнитуру программно
view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
Ответ 6
Похоже, вы используете 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>
Ответ 7
Если вы следуете первой теме, это должно работать: Здесь
Да с отражением. Это работает (на основе этого ответа):
(Примечание: это временное решение из-за отсутствия поддержки пользовательских шрифтов, поэтому, если вы хотите изменить эту ситуацию, пожалуйста, держите голосу, чтобы проголосовать за проблему с андроидом здесь). Примечание. Не оставляйте комментарии "я тоже" по этой проблеме, каждый, кто уставился на это, получает электронное письмо, когда вы это делаете. Так что просто "звезда", пожалуйста.
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>
Ответ 8
Создайте папку активов в главной папке шрифтов folder.add в ней. добавьте ваш файл .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
Ответ 9
Сначала создайте новый класс, который переопределяет любой вид, который вы хотите настроить. (например, хотите кнопку с пользовательским шрифтом? Расширить 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();
}
Теперь вы все настроены. Вы можете добавить больше атрибутов для чего угодно (вы могли бы добавить еще один для шрифта typeStyle - жирный, курсив и т.д.), Но теперь посмотрим, как его использовать:
<?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.
Последнее: если вы хотите использовать это в стиле (res/values/styles.xml
), вы не должны добавлять строку xmlns:custom
. Просто укажите имя атрибута без префикса:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
Ответ 10
Я тоже попробовал переопределить шрифты, но в конце это не надежное решение, к сожалению, более серьезные шрифты занимают больше. Вы можете либо дождаться выхода Android O с помощью специального шрифта, либо использовать стороннюю библиотеку.
Последнее решение, с которым я столкнулся, это библиотека Caligraphy, которую было легко инициировать и позволяло использовать столько шрифтов, сколько вы хотите, Проверяя его исходный код, я понял, почему просто переопределение шрифтов не будет работать, даже если вы не планируете его использовать. Я рекомендую прочитать его один раз..
Удачи.
Ответ 11
Попробуйте под кодом, он работает для меня, надеюсь, он тоже вам поможет.
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 на любую вашу активность или вы можете создать тот же класс для фрагмента, если вы используете.
Примечание. - Если вы хотите установить некоторые виды разного шрифта, тогда вы должны установить это программно, как показано ниже
private Typeface typeface;
typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold));
tvUserName.setTypeface(typeface);
Так что дайте ему попробовать и дайте мне знать, если я могу помочь вам дальше
Ответ 12
Работа вокруг для kotlin будет этим
Суть решения 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>
Ответ 13
- Вначале вы должны щелкнуть правой кнопкой мыши ресурсы вашего проекта с именем
res
, затем из опции new
выбрать Android Resource Directory
, выбрать font
форму Resource type
и нажать OK, это создаст каталог шрифтов для размещения ваших шрифтов. в этом.
![enter image description here]()
- Поместите туда файлы шрифтов
.ttf
.
![enter image description here]()
Перейти к файлу стиля проекта, который существует по следующему пути 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
, как описано выше.