将自定义字体设置为所有TextView

时间:2013-08-21 11:11:55

标签: android fonts

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

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

5 个答案:

答案 0 :(得分:13)

如果您需要为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);
    }
}

}

的themes.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设备(我猜他们可能会使用值-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+。不要覆盖value-v21样式中的字体。

只需覆盖values / style.xml中的字体,你就可以了:)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

是。只需创建一个样式并将其设置为某种字体,然后以该样式设置整个应用程序。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

活动中的调用方法为:

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

将Fragment中的方法调用为:

  Constants.overrideFonts(getActivity(), view);