Мне нужно использовать определенный шрифт для всего моего приложения. У меня есть файл .ttf для него. Можно ли установить это как шрифт по умолчанию, при запуске приложения, а затем использовать его в другом месте приложения? Когда он установлен, как его использовать в моих XML-макетах?Можно ли установить собственный шрифт для всего приложения?
ответ
Да, его можно установить шрифт для всего приложения.
Самый простой способ добиться этого - упаковать нужные шрифты (ы) с вашим приложением.
Чтобы сделать это, просто создать активы/ папку в корневом каталоге проекта, и поставить шрифты (в 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);
}
}
Хотя это не будет работать для целого приложения, оно будет работать для 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);
Надежда, что помогает.
Я думаю, что лучше всего было бы переопределить TextView. Этот метод может быть несколько избыточным, если у вас есть приложение с большим количеством просмотров. – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Это может ... но в соответствии с спецификациями Android вы хотите избежать макетов глубже 4 уровней и 100 просмотров в ширину (даже это совсем немного). Рекурсия может быть плохой с точки зрения производительности, но даже если ваш макет был 20 уровней, которые даже не значительны. – Tom
Я бы согласился, что это не оказывает заметного влияния на производительность, и я не пытаюсь сказать, что ваш ответ неверен. Мне просто не нравится ездить на велосипеде по каждому виду в макете, если мне это не нужно. Кроме того, расширяя TextView, если вы хотите изменить внешний вид другим способом, вам нужно будет только изменить код в одном месте. – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Я бы предложил расширить 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);
}
Я хотел бы также предложить расширение 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));
}
Будьте осторожны, когда делаете это на платформах до 4.0 - это приведет к утечке большого количества ресурсов из-за ошибки на Android: https://code.google.com/p/ android/issues/detail? id = 9904 –
Как обо всех других представлениях, которые используют шрифт .. –
как мы можем вернуться к умолчанию. Я делаю что-то вроде этого: if (configShared.getString ("storeId", AppCredentials.DEFAULT_STORE_ID) .equals ("2")) {final Field staticField = Typeface.class.getDeclaredField (staticTypefaceFieldName); staticField.setAccessible (истина); staticField.set (null, newTypeface); } else {final Поле staticField = Typeface.class.getDeclaredField (staticTypefaceFieldName); staticField.setAccessible (истина); staticField.set (null, null); } – Killer
Да с отражением. Эта работа (based on this answer):
(Примечание: это временное решение из-за отсутствия поддержки пользовательских шрифтов, поэтому, если вы хотите изменить эту ситуацию, пожалуйста, сделайте выбор, чтобы проголосовать за android issue here). Примечание: Не оставляйте комментарии «я тоже» по этой проблеме, каждый, кто уставился на это, получает электронное письмо, когда вы это делаете. Так что просто «звезда», пожалуйста.
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();
}
}
}
Затем нужно перегружать несколько шрифтов по умолчанию, например, в application классе:
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>
Это должен быть принятый ответ. Это хак-класс, но он просто работает. –
Портировано на C# (xamarin monodroid) - отлично работает! –
Очень умное решение! Выполняет риск изменения имен Typeface или переноса на новые классы, но я предполагаю, что они были такими, и где они находятся с Android 1.5, поэтому это разумно безопасный взлом.Вы можете кэшировать поля по имени для лучшей производительности (я думаю, в случае, когда приложение имеет темы и позволяет менять шрифты с помощью живой/мгновенной обратной связи). – 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.
его очень просто ... 1.Download и поставить ур специальный шрифт в assets..then написать один отдельный класс для просмотра текста следующим образом: здесь я использовал шрифт 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"
/>
Да, это работает :) Но что, если я хочу применять одни и те же шрифты для остальных остальных видов/виджетов? Нужно ли писать отдельный класс для всех других видов (включая диалоги/тосты/панели действий)? – NarendraJi
Да, для этого решения вам нужно написать отдельные классы для каждого из ваших представлений. –
Я хотел бы улучшить weston «s ответ на 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 положить начертания в статической переменной начертания шрифта.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();
}
}
}
хороший обход для L. Однако мне интересно, почему это, похоже, не работает для моих «кнопок Button и Tool Bar». Я переопределяю шрифт по умолчанию в MainApplication следующим образом: 'FontsOverride.setDefaultFont (это,« DEFAULT »,« MyFontAsset.ttf »);'. Я использую Nexus 5, v5.1.1 – kip2
Привет, Спасибо Это было очень полезно, только одно: это не работает на Android 6 (API 22). Затем следует изменить код на это: 'Build.VERSION.SDK_INT == 21' - Это как раз в' API 21' ** Я тестирую Nexus с API 22 ** – Saeid
Тем не менее я не могу установить собственный шрифт, используя этот метод в Nexus 9 –
Работа для 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>
Вы можете установить пользовательские шрифты для каждого макета по одному, только с одним вызовом функции из каждого макета, передавая ее корень View.First, создать singelton подход для доступа к объекту шрифта, как этот
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>
В макете Выше корневой идентификатор родительского «Main Родитель» теперь позволяет применять шрифт
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());
}
}
Ура :)
Ницца .. не более одного и того же шрифта воссоздать, только 1 шрифт используется для всех полей.:) –
Я также хотел бы улучшить Ответ Weston для API 21 Android 5.0.
У меня была такая же проблема на моем Samsung s5 при использовании шрифта DEFAULT. (С другими шрифтами он работает отлично)
мне удалось сделать его работу, установив начертание («Санс», например) в файлах XML, для каждого TextView или кнопки
<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 Class:
public class MyApplication extends Application {
@Override
public void onCreate() {
TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF",
"fonts/my_font.ttf");
}
}
Надеюсь, это поможет.
я написал класс назначая начертание мнения в текущей иерархии представлений и на основе зева текущие свойства начертания шрифта (жирный, нормальный, вы можете добавить другие стили, если вы хотите):
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);
}
}
}
}
Сейчас во всех фрагменты в onViewCreated или onCreateView, во всех видах деятельности в OnCreate и во всех адаптерах зрения в GetView или NewView просто вызвать:
typefaceAssigner.assignTypeface(view);
Я хотел бы улучшить weston «s и Roger Huang» s ответы на более 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>
Over (равный) 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 5.1 Primary Android System)
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<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);
}
}
Чтобы запустить код всего приложения вы должны написать в каком-то классе, как заявка на следующее:
new FontsOverride(this).loadFonts();
Создайте папку внутри «активов» «шрифтов» и поставить необходимые шрифты там. Простую инструкцию можно найти здесь: https://stackoverflow.com/a/31697103/2914140.
Устройство Lenovo также неправильно получает значение шрифта. В большинстве случаев он возвращает Typeface.NORMAL, иногда null. Даже если TextView выделен жирным шрифтом (в макете xml-файла). См. Здесь: TextView isBold always returns NORMAL. Таким образом, текст на экране всегда находится в обычном шрифте, не жирным или курсивом. Поэтому я думаю, что это ошибка производителя.
Я изучил исходный код Android, ваш ответ лучший из лучших. Он может заменить тонкий, средний, легкий или что-нибудь еще. Спасибо огромное! – user2912553
@ пользователь2912553, спасибо! – CoolMind
Существует большая библиотека для пользовательских шрифтов в андроиде: Calligraphy
вот пример, как использовать его.
В Gradle вам нужно поместить эту строку в сборку вашего приложения.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">
, и он изменит всю деятельность на ваш шрифт! это просто и чисто!
Это идеальное решение. –
Правда, это очень идеальное решение, поэтому мне не нужно писать разные классы, чтобы обновлять шрифты для пунктов меню, переключателя или флажка. Это относится ко всем !! спасибо :) – Manisha
Определенно не идеальное решение: жирные/курсивные/полужирные шрифты перезаписываются. В настоящее время нет простого способа установить эти семьи. – 0101100101
В итоге:
Вариант # 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();
}
}
}
}
Использование в классе Application:
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>
Option2: Подкласс каждый вид, в котором вам нужно настроить шрифт, то есть. ListView, EditTextView, кнопки и т.д. (Palani «s ответ):
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: Реализовать Просмотр Crawler, который проходит через иерархию зрения текущего экрана:
Вариант # 1 (ответ Tom «s):
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: Использование стороннего лидера под названием Calligraphy.
Лично я бы рекомендовал вариант № 4, так как он сэкономит много головных болей.
В * Варианте # 1 *, что вы подразумеваете под '' sans-serif'' в 'newMap.put (' и 'monospace' в' styles'?! Я хочу использовать пользовательский шрифт с именем 'barana.ttf'. –
This Решение не работает корректно в некоторых ситуациях.
Я выдвигаю его:
FontsReplacer.Java
public class MyApplication extends Application {
@Override
public void onCreate() {
FontsReplacer.replaceFonts(this);
super.onCreate();
}
}
https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805
Calligraphy работает довольно хорошо, но он не подходит для меня, так как он не поддерживает различные веса (полужирный, курсив и т.д.) для шрифта-семьи.
Итак, я попробовал 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);
}
}
Не идеальное решение. Для этого решения потребуются индивидуальные обходные пути для доступа к стандарту Android' TextView's – blueware
на Android O это теперь можно определить непосредственно из XML и my bug is now closed!
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>
Наслаждайтесь!
. Спасибо. Мы должны использовать Android Studio 2.4 для возможности добавления папки шрифтов. –
делает это работа для всего приложения? – SolidSnake
На самом деле мне просто нужно применить его к моему стилю, и он будет применяться через приложение, но некоторые (программно добавленные элементы управления должны быть применены через Java-код) – SolidSnake
в апи 26 с build.gradle 3.0.0 вы можете создать каталог шрифтов в разрешении и использовать эту строку в стиле
<item name="android:fontFamily">@font/your_font</item>
для изменения build.gradle это в вашем build.gradle dependecies
classpath 'com.android.tools.build:gradle:3.0.0'
Наконец, Google понял всю серьезность этой проблемы (применения пользовательских шрифтов для компонентов пользовательского интерфейса), и они разработали чистое решение для него.
Во-первых, вам необходимо обновить библиотеку поддержки 26+ (возможно, вам также потребуется обновить студию gradle {4.0+}, android studio), затем вы можете создать новую папку ресурсов, называемую шрифтом. В этой папке вы можете разместить свои ресурсы шрифта (.tff, ...). Тогда вам необходимо изменить значение по умолчанию приложения их и заставить свой собственный шрифт в это :)
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">@font/my_custom_font</item>
</style>
Примечания: если вы хотите, чтобы поддерживать устройства с более старым API, чем 16, вы должны использовать приложение имена вместо андроида!
Для изменения семейства шрифтов шрифтов TextViews переопределите textViewStyle в теме приложения.
Для использования пользовательского шрифта в fontFamily используйте ресурсы шрифта, которые находятся в библиотеке поддержки.
Функция была добавлена в Android 26, но в более ранних версиях была добавлена поддержка поддержки.
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
- 1. Можно ли установить TextRenderingHint для всего приложения?
- 2. Установить шрифт универсально для всего приложения
- 3. как установить шрифт Roboto для всего приложения?
- 4. Android: установить шрифт всего приложения
- 5. Можно ли установить собственный шрифт и размер для NSString?
- 6. Пользовательский шрифт для всего приложения
- 7. Изменить шрифт всего приложения
- 8. Roboto шрифт для всего приложения
- 9. Можно ли изменить шрифт всего приложения в jQuery mobile
- 10. Как применить шрифт для всего приложения?
- 11. Можно ли установить глобальное RoutePrefix для всего приложения MVC?
- 12. Как установить шрифт телефона по умолчанию для всего моего приложения
- 13. Как установить пользовательский шрифт для всего приложения в Android
- 14. android: как установить пользовательский шрифт для всего приложения
- 15. Как создать собственный шрифт для приложения Blackberry
- 16. Установите стандартный шрифт по умолчанию для всего приложения Xamarin.iOS?
- 17. Есть ли способ установить шрифт для всего электронного письма?
- 18. Можно ли установить фон всего приложения в React Native?
- 19. Редактор Дарта можно использовать собственный шрифт?
- 20. Изменить системный шрифт для приложения iPhone - всего приложения
- 21. Как установить собственный шрифт для всех ярлыков в представлении?
- 22. Как установить собственный шрифт внутри виджета iBook?
- 23. Как установить собственный шрифт в UltraWinGrid?
- 24. Установить собственный шрифт в адаптере RecyclerView
- 25. Как установить пользовательский шрифт для приложения форм xamarinf
- 26. Как настроить пользовательский шрифт для всего приложения на Android?
- 27. Как установить шрифт для меню «Параметры»?
- 28. Как установить собственный шрифт для метки в пользовательском tableviewcelll?
- 29. Можно ли создать экземпляр нестатического класса для всего приложения WPF?
- 30. Моноширинный шрифт и собственный шрифт (Marshmallow)
Проверить это http://www.gadgetsaint.com/android/custom-fonts-textview-edittext-android/#.WNive2996Hs – ASP