我在我的应用程序中使用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>

当前回答

这是我的项目的工作,来源https://gist.github.com/artem-zinnatullin/7749076

在资产文件夹内创建字体目录,然后复制您的自定义字体到字体目录,例如我使用trebuchet.ttf;

创建一个类TypefaceUtil.java;

import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;

import java.lang.reflect.Field;
public class TypefaceUtil {

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

        }
    }
}

在styles.xml中编辑主题

<item name="android:typeface">serif</item>

My styles.xml中的示例

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:typeface">serif</item><!-- Add here -->
    </style>


    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>
</resources>

最后,在Activity或Fragment中onCreate调用TypefaceUtil.java

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TypefaceUtil.overrideFont(getContext(), "SERIF", "fonts/trebuchet.ttf");
    }

其他回答

我们是这样做的:

private static void OverrideDefaultFont(string defaultFontNameToOverride, string customFontFileNameInAssets, AssetManager assets)
{
    //Load custom Font from File                
    Typeface customFontTypeface = Typeface.CreateFromAsset(assets, customFontFileNameInAssets);

    //Get Fontface.Default Field by reflection
    Class typeFaceClass = Class.ForName("android.graphics.Typeface");
    Field defaultFontTypefaceField = typeFaceClass.GetField(defaultFontNameToOverride);

    defaultFontTypefaceField.Accessible = true;
    defaultFontTypefaceField.Set(null, customFontTypeface);
}

仅仅设置应用程序的字体为普通,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参考

答案是否定的,你不能。 是否可以为整个应用程序设置自定义字体? 获取更多信息。

有一些变通方法,但没有“在这里写一行代码,我所有的字体都将是这个而不是那个”。

(我有点感谢谷歌和苹果公司)。自定义字体是有一席之地的,但如果让它们在整个应用程序范围内容易被取代,就会创造出一个Comic Sans应用程序的整个世界)

不谈性能,对于自定义字体,你可以有一个递归方法循环通过所有的视图和设置字体,如果它是一个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 Oreo的发布,您可以使用支持库来实现这一目标。

签入你的应用构建。Gradle,如果你有支持库>= 26.0.0 添加"font"文件夹到你的资源文件夹,并添加你的字体 在你的应用程序主样式中引用你的默认字体家族: <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <项目名称= " android: fontFamily " > @font / your_font > < /项目 <item name="fontFamily">@font/your_font</item> <!——目标android sdk版本< 26和> 14如果主题不是AppCompat——> > < /风格

更多详细信息请访问https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html。