能否为整个应用设置自定义字体?

275

我需要在整个应用程序中使用某种特定字体。我有相应的.ttf文件。 是否可以在应用程序启动时将其设置为默认字体,然后在应用程序的其他地方使用它?设置后,我该如何在我的布局XML中使用它?


在Android Studio 3.0中,您可以轻松设置自定义字体:https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml - MHSaffari
@MHSFisher 字体在 XML 中是 Android 8.0(API 级别 26)的一个功能。 - Emad Razavi
1
@EmiRaz 请阅读文档 https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml#using-support-lib。该功能已添加到支持库26中,但支持API 16及以上版本。 - MHSaffari
25个回答

455

是的,带有反射。这个方法可行 (基于这个答案):

(注意:这是一种绕过自定义字体支持不足的解决办法,因此如果您想改变这种情况,请点亮并赞成此处的Android问题)。注意: 不要在该问题上留下“我也是”评论,每个已观注它的人在您这样做时都会收到一封电子邮件。所以请只是“点亮”它。

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {

    public static void setDefaultFont(Context context,
            String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(),
                fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    }

    protected static void replaceFont(String staticTypefaceFieldName,
            final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

接下来您需要重载一些默认字体,例如在应用程序类中:

public final class Application extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    }
}

当然,如果您使用相同的字体文件,您可以改进此操作以仅加载一次。

但是,我倾向于只覆盖一个字体,比如"MONOSPACE",然后设置一种风格来强制在整个应用程序中应用该字体类型:

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

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:typeface">monospace</item>
    </style>
</resources>

API 21 Android 5.0

我已经调查了评论中的报告,发现它似乎与主题 android:Theme.Material.Light 不兼容。

如果您不重视该主题,请使用较旧的主题,例如:

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>

11
如何覆盖等宽粗体或斜体样式? - Christopher Rivera
2
@ChristopherRivera 有 "DEFAULT_BOLD",但也有一个私有字段:private static Typeface[] sDefaults; 您可以尝试通过反射访问它,并将 sDefaults[Typeface.ITALIC] 设置为您的 Typeface。请参见 此链接 - weston
5
@weston 不用担心,我已经搞定了。我之前理解有误。你做得很好。你能告诉我一个问题吗?为什么不适用于默认字体?我按照你的建议将字体更改为等宽字体并应用逻辑,这个方法奏效了。但是对于默认字体却无法奏效。 - Jay Pandya
2
无法创建本地字体错误。通过添加字体路径进行修复。"FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/MyFontAsset.ttf"); " - Sai
3
我发现必须到处更换默认的“TextView”以使用自定义字体或使用像这样的反射解决方案真的很烦人。再加上 Android 中可用字体的数量有限,这使得开发出外观好看的应用程序变得非常困难。我已经向 Android 问题跟踪器添加了一个功能请求。如果您想看到此功能,则可以在此处标记该问题:https://code.google.com/p/android/issues/detail?id=187475&thanks=187475&ts=1443175244 - Sam
显示剩余42条评论

65

Android有一个非常棒的自定义字体库:Calligraphy

这里是如何使用它的示例。

在Gradle中,您需要将以下行放入您的应用程序的build.gradle文件中:

dependencies {
    compile 'uk.co.chrisjenx:calligraphy:2.2.0'
}

然后创建一个继承 Application 的类,并编写以下代码:

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                        .setDefaultFontPath("your font path")
                        .setFontAttrId(R.attr.fontPath)
                        .build()
        );
    }
} 

在活动类中,在onCreate方法之前添加以下方法:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

最后,你的清单文件应该像这样:

<application
   .
   .
   .
   android:name=".App">

它会将整个活动更改为您的字体! 这很简单、干净!


1
这是完美的解决方案。 - nizam.sp
1
是的,这是非常完美的解决方案,我不需要编写不同的类来更新菜单项、单选按钮或复选框字体。它适用于所有情况!谢谢 :) - Manisha
2
绝对不是完美的解决方案:粗体/斜体/粗斜体样式被覆盖。目前没有简单的方法来设置这些字体族。 - 0101100101
2
如果我这样做,我该如何从粗体切换到常规字体? - GMX
2
为了获得加粗、斜体或下划线功能,我在strings.xml文件中使用了<b></b><u></u><i></i>标签,目前看来它可以正常工作。 - jlively
显示剩余4条评论

47

虽然这种方法不能用于整个应用程序,但可以用于一个Activity,并且可以在任何其他Activity中重复使用。我已经感谢 @FR073N 的帮助更新了我的代码以支持其他视图。我不确定关于 ButtonsRadioGroups 等的问题,因为这些类都扩展自 TextView,所以它们应该能够正常工作。我添加了一个布尔条件来使用反射,因为它似乎非常破坏性,可能会明显影响性能。

注意:正如指出的那样,这对于动态内容是行不通的!对于这种情况,可以通过调用此方法,例如使用 onCreateViewgetView 方法,但需要额外的努力。

/**
 * Recursively sets a {@link Typeface} to all
 * {@link TextView}s in a {@link ViewGroup}.
 */
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{
    if (mContainer == null || mFont == null) return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children.
    for (int i = 0; i < mCount; ++i)
    {
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView)
        {
            // Set the font if it is a TextView.
            ((TextView) mChild).setTypeface(mFont);
        }
        else if (mChild instanceof ViewGroup)
        {
            // Recursively attempt another ViewGroup.
            setAppFont((ViewGroup) mChild, mFont);
        }
        else if (reflect)
        {
            try {
                Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
                mSetTypeface.invoke(mChild, mFont); 
            } catch (Exception e) { /* Do something... */ }
        }
    }
}
然后你可以像这样使用它:
final Typeface mFont = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"); 
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, mFont);

希望能帮到你。


4
我认为最好的方法是覆盖textview。如果您的应用程序有很多视图,这种方法可能会变得有些冗长。 - zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
1
根据Android规范,你应该避免布局深度超过4级和宽度超过100个视图(即使这已经相当多了)。递归在性能方面可能不好,但即使您的布局有20个级别,也不会显著影响性能。 - Tom
1
只是想补充一下,上面的代码只涵盖了TextViews,但ListViews、Alerts、Toasts、Map Markers等仍将使用系统字体。 - csch
谢谢你提供的代码,但是ListView和Buttons上的字体没有改变,菜单也是一样。 - Bacara
2
这个函数需要3个参数,当你递归调用它时,你传递了2个参数?哪一个是正确的?什么是反射? - MBH
显示剩余9条评论

34

总之:

选项#1:使用反射来应用字体(结合westonRoger Huang的回答):

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride { 

    public static void setDefaultFont(Context context,
            String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(),
                fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    } 

    protected static void replaceFont(String staticTypefaceFieldName,final Typeface newTypeface) {
        if (isVersionGreaterOrEqualToLollipop()) {
            Map<String, Typeface> newMap = new HashMap<String, Typeface>();
            newMap.put("sans-serif", newTypeface);
            try {
                final Field staticField = Typeface.class.getDeclaredField("sSystemFontMap");
                staticField.setAccessible(true);
                staticField.set(null, newMap);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            try {
                final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
                staticField.setAccessible(true);
                staticField.set(null, newTypeface);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } 
        }
    }

} 

在 Application 类中的用法:

public final class Application extends android.app.Application {
    @Override 
    public void onCreate() { 
        super.onCreate(); 
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    } 
} 

根据lovefish的方法,设置一个样式以强制应用字体类型在整个应用中生效:

Android 5.0以下版本(Pre-Lollipop):

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

棒棒糖(API 21):

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:textAppearance">@style/CustomTextAppearance</item>
   </style>

   <style name="CustomTextAppearance">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

选项2:为需要自定义字体的每个视图子类化,即ListView、EditText、Button等。(Palani的答案):

public class CustomFontView extends TextView {

public CustomFontView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(); 
} 

public CustomFontView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(); 
} 

public CustomFontView(Context context) {
    super(context);
    init(); 
} 

private void init() { 
    if (!isInEditMode()) {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
        setTypeface(tf);
    } 
} 

选项3:实现一个视图爬虫来遍历当前屏幕的视图层次结构:

变体#1(Tom的回答):

public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{ 
    if (mContainer == null || mFont == null) return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children. 
    for (int i = 0; i < mCount; ++i)
    { 
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView)
        { 
            // Set the font if it is a TextView. 
            ((TextView) mChild).setTypeface(mFont);
        } 
        else if (mChild instanceof ViewGroup)
        { 
            // Recursively attempt another ViewGroup. 
            setAppFont((ViewGroup) mChild, mFont);
        } 
        else if (reflect)
        { 
            try { 
                Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
                mSetTypeface.invoke(mChild, mFont); 
            } catch (Exception e) { /* Do something... */ }
        } 
    } 
} 

使用方法:

final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"));

变化#2: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere.

选项#4:使用第三方库Calligraphy

个人建议选择选项#4,因为它可以避免很多麻烦。


选项#1中,newMap.put()中的sans-serifstyles中的monospace是什么意思?!我想使用一个名为barana.ttf的自定义字体。 - Dr.jacky
在选项1中,第一个代码片段无法与API级别22、Android 5.1.1一起使用。但是另一个代码部分可以。那么应该是什么确切的if条件呢? - user1510006

28

我希望你能翻译并改进weston在API 21 Android 5.0中的答案。

原因

在API 21下,大多数文本样式都包含fontFamily设置,例如:

<style name="TextAppearance.Material">
     <item name="fontFamily">@string/font_family_body_1_material</item>
</style>

应用默认的Roboto Regular字体:

<string name="font_family_body_1_material">sans-serif</string>

原始答案未能应用等宽字体,因为android:fontFamily优先级高于android:typeface属性(参考)。使用Theme.Holo.*是一个有效的解决方法,因为里面没有android:fontFamily设置。
解决方案
自从Android 5.0将系统字体放入静态变量Typeface.sSystemFontMap (参考)中,我们可以使用相同的反射技术来替换它:
protected static void replaceFont(String staticTypefaceFieldName,
        final Typeface newTypeface) {
    if (isVersionGreaterOrEqualToLollipop()) {
        Map<String, Typeface> newMap = new HashMap<String, Typeface>();
        newMap.put("sans-serif", newTypeface);
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField("sSystemFontMap");
            staticField.setAccessible(true);
            staticField.set(null, newMap);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    } else {
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

4
对于L,有一个不错的解决方法。然而,我想知道为什么这似乎对我的“Button”和工具栏标题无效。我正在覆盖MainApplication中的默认字体,如下所示:FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");。我使用的是Nexus 5,版本为5.1.1。 - kip2
3
嘿, 谢谢。 这很有帮助,只有一件事:在Android 6(API 22)上无法使用。 那么代码应该更改为:Build.VERSION.SDK_INT == 21
  • 这仅适用于API 21我在API 22的Nexus上测试过。
- Saeid
仍然无法在Nexus 9上使用此方法设置自定义字体。 - Rahul Upadhyay
2
有人遇到5.1+版本无法工作的问题。不要在你的values-v21样式中覆盖字体。 - Muhammad Babar
@MuhammadBabar 谢谢,你的解决方案让我度过了美好的一天。 - M.Yogeshwaran
第一段代码片段在API级别22,即Android 5.1.1上无法工作。但是另一个代码部分可以。那么确切的if条件应该是什么? - user1510006

15

非常简单... 1. 下载并将您的自定义字体放在资产中...然后编写一个单独的文本视图类,如下所示:这里我使用了 Futura 字体

public class CusFntTextView extends TextView {

public CusFntTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

public CusFntTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CusFntTextView(Context context) {
    super(context);
    init();
}

private void init() {
    if (!isInEditMode()) {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
        setTypeface(tf);
    }
}

}

并在XML中执行以下操作:

 <com.packagename.CusFntTextView
        android:id="@+id/tvtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"         
        android:text="Hi Android"           
        android:textAppearance="?android:attr/textAppearanceLarge"
      />

没错,那个方法可以用 :) 但是,如果我想要将相同的字体应用于其他剩余的视图/小部件,该怎么办呢?我需要为所有其他视图(包括对话框/吐司/操作栏)编写单独的类吗? - Narendra Singh
是的,对于这个解决方案,您需要为每个视图编写单独的类。 - Saad Bilal

9
我建议扩展TextView和其他控件,但最好在构造函数中设置字体。
public FontTextView(Context context) {
    super(context);
    init();
}

public FontTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public FontTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

protected void init() {
    setTypeface(Typeface.createFromAsset(getContext().getAssets(), AppConst.FONT));
}

2
在4.0之前的平台上进行此操作时要小心 - 这将由于Android中的一个错误而泄漏大量资源:https://code.google.com/p/android/issues/detail?id=9904 - Ryan M
我们如何恢复默认设置。我正在做这样的事情:如果(configShared.getString("storeId", AppCredentials.DEFAULT_STORE_ID).equals("2")){final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);staticField.setAccessible(true);staticField.set(null, newTypeface);}else{final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);staticField.setAccessible(true);staticField.set(null, null);} - Shubham AgaRwal

8
我希望能够改进 westonRoger Huang 的答案,以适用于 API 21 及以上版本的 Android Lollipop,并使用 "Theme.AppCompat" 主题。

Android 4.4 及以下版本:

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

超过(等于)API 5.0

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:textAppearance">@style/CustomTextAppearance</item>
   </style>

   <style name="CustomTextAppearance">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

FontsOverride实用程序文件与weston的答案中所述的相同。 我已在以下手机上进行了测试:

Nexus 5(Android 5.1主要Android系统)

ZTE V5(Android 5.1 CM12.1)

XIAOMI Note(Android 4.4 MIUI6)

HUAWEI C8850(Android 2.3.5未知)


8
在这里可以找到一个绝妙的解决方案:https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere。只需从BaseActivity扩展活动并编写这些方法。此外,你最好像这里描述的那样缓存字体。
经过一番研究,我编写了能够在三星Galaxy Tab A(Android 5.0)上运行的代码。使用了Weston和Roger Huang的代码以及这里的代码。还在Lenovo TAB 2 A10-70L上进行了测试,但不能正常工作。我在这里插入了一个“Comic Sans”字体,以便看到区别。
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class FontsOverride {
    private static final int BOLD = 1;
    private static final int BOLD_ITALIC = 2;
    private static final int ITALIC = 3;
    private static final int LIGHT = 4;
    private static final int CONDENSED = 5;
    private static final int THIN = 6;
    private static final int MEDIUM = 7;
    private static final int REGULAR = 8;

    private Context context;

    public FontsOverride(Context context) {
        this.context = context;
    }

    public void loadFonts() {
        Map<String, Typeface> fontsMap = new HashMap<>();
        fontsMap.put("sans-serif", getTypeface("comic.ttf", REGULAR));
        fontsMap.put("sans-serif-bold", getTypeface("comic.ttf", BOLD));
        fontsMap.put("sans-serif-italic", getTypeface("comic.ttf", ITALIC));
        fontsMap.put("sans-serif-light", getTypeface("comic.ttf", LIGHT));
        fontsMap.put("sans-serif-condensed", getTypeface("comic.ttf", CONDENSED));
        fontsMap.put("sans-serif-thin", getTypeface("comic.ttf", THIN));
        fontsMap.put("sans-serif-medium", getTypeface("comic.ttf", MEDIUM));
        overrideFonts(fontsMap);
    }

    private void overrideFonts(Map<String, Typeface> typefaces) {
        if (Build.VERSION.SDK_INT == 21) {
            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", "Cannot set custom fonts");
            }
        } else {
            try {
                for (Map.Entry<String, Typeface> entry : typefaces.entrySet()) {
                    final Field staticField = Typeface.class.getDeclaredField(entry.getKey());
                    staticField.setAccessible(true);
                    staticField.set(null, entry.getValue());
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    private Typeface getTypeface(String fontFileName, int fontType) {
        final Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontFileName);
        return Typeface.create(tf, fontType);
    }
}

为了在整个应用程序中运行代码,您应该在某个类(比如Application)中编写以下内容:
    new FontsOverride(this).loadFonts();

创建一个文件夹“fonts”在“assets”中,并将所需字体放入其中。可以在这里找到简单的说明:https://dev59.com/GGYr5IYBdhLWcg3wnrZ0#31697103
联想设备也会错误地获取字体类型的值。大多数时候它会返回Typeface.NORMAL,有时是null。即使TextView在xml文件布局中加粗。请参见此处:TextView isBold always returns NORMAL。这样屏幕上的文本始终是普通字体,而不是粗体或斜体。因此,我认为这是生产商的一个错误。

我研究了 Android 源代码,你的回答是最好的一个。它可以替代 thin(细)、medium(中等)、light(轻)或任何其他东西。非常感谢你! - momvart

6

在Xamarin.Android工作:

类:

public class FontsOverride
{
    public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
    {
        Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
        ReplaceFont(staticTypefaceFieldName, regular);
    }

    protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
    {
        try
        {
            Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
            staticField.Accessible = true;
            staticField.Set(null, newTypeface);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

应用程序实施:

namespace SomeAndroidApplication
{
    [Application]
    public class App : Application
    {
        public App()
        {

        }

        public App(IntPtr handle, JniHandleOwnership transfer)
            : base(handle, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
        }
    }
}

样式:

<style name="Theme.Storehouse" parent="Theme.Sherlock">
    <item name="android:typeface">monospace</item>
</style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接