有没有一种简单的方法,可以使我的应用程序中所有的textviews(和其他文本元素)都使用我自己的自定义字体(而不是内置选择),而不必通过textview.setTypeface()手动设置它们?
我猜扩展Textview会起作用,但是使用可视化编辑器构建界面有点麻烦。我想到了类似于样式的东西,但找不到如何在那里设置自定义字体。
有没有一种简单的方法,可以使我的应用程序中所有的textviews(和其他文本元素)都使用我自己的自定义字体(而不是内置选择),而不必通过textview.setTypeface()手动设置它们?
我猜扩展Textview会起作用,但是使用可视化编辑器构建界面有点麻烦。我想到了类似于样式的东西,但找不到如何在那里设置自定义字体。
public class MyApp extends Application {
@Override
public void onCreate()
{
TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf");
}
}
TypefaceUtil.java
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("TypefaceUtil","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
}
}
}
主题.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAppTheme" parent="@android:style/Theme.Holo.Light">
<!-- you should set typeface which you want to override with TypefaceUtil -->
<item name="android:typeface">serif</item>
</style>
</resources>
适用于Android 5.0或更高版本的更新
我经过调查和在运行API 5.0或更高版本的设备上进行测试,发现该解决方案效果很好,因为我正在使用单个style.xml文件,而不是在values-21文件夹中创建其他style.xml文件。
尽管如此,有些用户告诉我这个解决方案在Android 5.0设备上无法正常工作(我猜他们可能在使用values-21 style.xml)。
原因是,在API 21以下的大多数文本样式中包括fontFamily设置,比如:
<item name="fontFamily">@string/font_family_body_1_material</item>
应用默认的Roboto常规字体:
<string name="font_family_body_1_material">sans-serif</string>
所以最好的解决方案是
如果有人遇到5.0以上版本无法工作的问题,请不要在您的values-v21样式中覆盖typeface。
只需在values/style.xml中覆盖字体,您就可以使用了 :)
public static 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(Typeface.createFromAsset(context.getAssets(), "font/Lato-Regular.ttf"));
} else if (v instanceof EditText) {
((EditText) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "font/Lato-Regular.ttf"));
} else if (v instanceof Button) {
((Button) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "font/Lato-Regular.ttf"));
}
} catch (Exception e) {
}
}
在活动中调用方法:
Constants.overrideFonts(MainActivity.this, getWindow().getDecorView().getRootView());
在Fragment中调用方法的方式如下:
Constants.overrideFonts(getActivity(), view);
可以的。只需创建一个样式并将其设置为特定字体,然后将整个应用程序设置为该样式即可。