如果您需要为 android 应用程序中的所有 TextView 设置一种字体,您可以使用此解决方案。它将覆盖所有 TextView 的字体,包括操作栏和其他标准组件,但不会覆盖 EditText 的密码字体。
MyApp.java
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 Regular 字体:
<string name="font_family_body_1_material">sans-serif</string>
所以最好的解决方案是
如果任何人在 5.0+ 上遇到问题。不要在你的 values-v21 样式中覆盖字体。
只需覆盖 values/style.xml 中的字体就可以了:)