【问题标题】:Setting custom font to all TextViews将自定义字体设置为所有 TextView
【发布时间】:2013-08-23 17:37:06
【问题描述】:

有没有一种简单的方法可以让所有文本视图(以及我的应用程序中的任何其他文本元素)使用我自己的自定义字体(而不是内置选择),而无需通过 textview.setTypeface 手动设置它们()?

我想扩展 Textview 可以解决问题,但是使用可视化编辑器构建界面有点痛苦。我正在考虑样式之类的东西,但找不到如何在那里设置自定义字体。

【问题讨论】:

标签: android fonts


【解决方案1】:

如果您需要为 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 中的字体就可以了:)

【讨论】:

  • 在很多设备上都很好用。但我正在尝试一些设备,例如三星 S5 (5.0.1),但它无法正常工作。
  • @Lena 我们正在使用@style/Theme.AppCompat.Light.NoActionBar 但这个不起作用
  • 你收到的结果是什么?
  • 这是来源吗? github gist by artem-zinnatullin - 如果是,那么你应该给予学分,如果不是,那么你应该在这个要点上要求学分。
  • 已在我的应用程序中实现了上述方法。它适用于大多数语言。但在 4.4.4 三星设备缅甸字体未正确加载。请建议。应用图片截图在这里 -> ibb.co/gvzOXv
【解决方案2】:

您可以创建一个方法来为公共类中的 textview 设置字体,您可以设置调用该方法并将 textview 作为其属性发送。

【讨论】:

    【解决方案3】:

    是的。只需制作一种样式并将其设置为某种字体,然后将整个应用程序设置为该样式即可。

    【讨论】:

      【解决方案4】:

      您可以通过创建 TextView 的子类并在其中调用 setTypeFace 方法来实现。例如在构造函数中。

      【讨论】:

        【解决方案5】:

        在 Constants 类中创建一个方法,以便可以从所有片段和活动中访问它:

         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) {
            }
        }
        

        在activity中调用方法为:

         Constants.overrideFonts(MainActivity.this, getWindow().getDecorView().getRootView());
        

        在 Fragment 中调用方法为:

          Constants.overrideFonts(getActivity(), view);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-23
          • 2015-10-17
          • 1970-01-01
          • 1970-01-01
          • 2023-03-26
          • 2011-08-27
          相关资源
          最近更新 更多