首页 > 解决方案 > 防止自定义系统字体覆盖应用程序字体

问题描述

设备之类的Samsung允许用户设置custom system fonts。问题是这些字体可能会覆盖我的应用程序fonts。我的意思是,如果我Arial font在我的应用程序中设置并且我在我的手机上设置了Calibri字体,那么将被.system fontArialCalibri font

如何预防这种情况?

标签: javaandroidandroid-studio

解决方案


  • “如果您需要为应用程序中的所有字体设置一种字体,TextView'sAndroid 可以使用此解决方案。
  • 它将覆盖所有 TextView's字体,包括Action Bar自定义系统字体和其他标准组件,但EditText's不会覆盖密码字体。”(原因很明显)。

  • 用于reflection覆盖默认字体和Application类。

  • 注意:不要忘记将应用程序主题的字体设置为将被覆盖的默认字体

MyApp.java

public class MyApp extends Application {

  @Override
  public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
  }
}

资源/主题.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>

TypefaceUtil.java

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 custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

资产/字体/Roboto-Regular.ttf:

你的字体放在这里,例如Arial

参考1

作者Artem Zinnatullin


推荐阅读