我在我的应用程序中使用Roboto light字体。要设置字体,我必须添加android:fontFamily="sans-serif-light"到每个视图。有什么方法来声明Roboto字体作为默认字体家族整个应用程序?我试过这样做,但似乎不管用。

<style name="AppBaseTheme" parent="android:Theme.Light"></style>

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

当前回答

要改变你的应用字体遵循以下步骤:

在res目录中创建一个新目录并命名为font。 插入字体.ttf/。在字体文件夹otf,确保字体名称是小写字母和下划线。 Inside res -> values -> styles.xml Inside <resources> -> <style>添加你的字体<item name="android:fontFamily">@font/font_name</item>。

现在你所有的应用文本都应该是你添加的字体。

其他回答

不谈性能,对于自定义字体,你可以有一个递归方法循环通过所有的视图和设置字体,如果它是一个TextView:

public class Font {
    public static void setAllTextView(ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setAllTextView((ViewGroup) child);
            } else if (child instanceof TextView) {
                ((TextView) child).setTypeface(getFont());
            }
        }
    }

    public static Typeface getFont() {
        return Typeface.createFromAsset(YourApplicationContext.getInstance().getAssets(), "fonts/whateverfont.ttf");
    }
}

在你的所有活动中,在setContentView之后将当前ViewGroup传递给它,就完成了:

ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
Font.setAllTextView(group);

对于片段,也可以做类似的事情。

Android并没有在整个应用程序中应用字体的方式上提供很多支持(参见本期)。你有4个选项来设置整个应用程序的字体:

选项1:应用反射来更改系统字体 选项2:为每个需要自定义字体的视图创建并子类化自定义视图类 Option3:实现一个遍历视图的视图爬虫 当前屏幕的层次结构 选项4:使用第三方库。

这些选项的详细信息可以在这里找到。

仅仅设置应用程序的字体为普通,sans, serif或monospace(不是自定义字体!),你可以这样做。

定义一个主题,并将android:typeface属性设置为你想在styles.xml中使用的字体:

<resources>

    <!-- custom normal activity theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- other elements -->
        <item name="android:typeface">monospace</item>
    </style>

</resources>

在AndroidManifest.xml文件中将主题应用到整个应用:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application
        android:theme="@style/AppTheme" >
    </application>
</manifest>

android参考

另一种方法是在整个应用程序中使用基于这个答案的反射

public class TypefaceUtil {
    /**
     * Using reflection to override default typefaces
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE
     * OVERRIDDEN
     *
     * @param typefaces map of fonts to replace
     */
    public static void overrideFonts(Map<String, Typeface> typefaces) {
        try {
            final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
            if (oldFonts != null) {
                oldFonts.putAll(typefaces);
            } else {
                oldFonts = typefaces;
            }
            field.set(null, oldFonts);
            field.setAccessible(false);
        } catch (Exception e) {
            Log.e("TypefaceUtil", "Can not set custom fonts");
        }
    }

    public static Typeface getTypeface(int fontType, Context context) {
        // here you can load the Typeface from asset or use default ones
        switch (fontType) {
            case BOLD:
                return Typeface.create(SANS_SERIF, Typeface.BOLD);
            case ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.ITALIC);
            case BOLD_ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.BOLD_ITALIC);
            case LIGHT:
                return Typeface.create(SANS_SERIF_LIGHT, Typeface.NORMAL);
            case CONDENSED:
                return Typeface.create(SANS_SERIF_CONDENSED, Typeface.NORMAL);
            case THIN:
                return Typeface.create(SANS_SERIF_MEDIUM, Typeface.NORMAL);
            case MEDIUM:
                return Typeface.create(SANS_SERIF_THIN, Typeface.NORMAL);
            case REGULAR:
            default:
                return Typeface.create(SANS_SERIF, Typeface.NORMAL);
        }
    }
}

然后当你想重写字体时,你可以调用这个方法并给它一个字体映射,如下所示:

Typeface regular = TypefaceUtil.getTypeface(REGULAR, context);
Typeface light = TypefaceUtil.getTypeface(REGULAR, context);
Typeface condensed = TypefaceUtil.getTypeface(CONDENSED, context);
Typeface thin = TypefaceUtil.getTypeface(THIN, context);
Typeface medium = TypefaceUtil.getTypeface(MEDIUM, context);
Map<String, Typeface> fonts = new HashMap<>();
fonts.put("sans-serif", regular);
fonts.put("sans-serif-light", light);
fonts.put("sans-serif-condensed", condensed);
fonts.put("sans-serif-thin", thin);
fonts.put("sans-serif-medium", medium);
TypefaceUtil.overrideFonts(fonts);

完整的示例检查

这只适用于Android SDK 21及以上的早期版本,检查完整的示例

答案是肯定的。

TextView和Button类的Global Roboto light:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="RobotoButtonStyle" parent="android:Widget.Holo.Button">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

只需从list themes.xml中选择您想要的样式,然后根据原始样式创建您的自定义样式。最后,应用样式作为应用程序的主题。

<application
    android:theme="@style/AppTheme" >
</application>

它只适用于像Roboto这样的内置字体,但这就是问题所在。对于自定义字体(例如从资产中加载),此方法将不起作用。

编辑08/13/15

如果你使用AppCompat主题,记得删除android:前缀。例如:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="buttonStyle">@style/RobotoButtonStyle</item>
</style>

注意buttonStyle不包含android: prefix,但textViewStyle必须包含它。