如何在一个地方为整个 Xamarin.Android 应用程序设置 fontFamily?

How to set fontFamily for the entire Xamarin.Android application in a single place?

我想设置 fontFamily 工具栏的文本、按钮、TextView 以及 Xamarin.Andrid 应用程序的所有文本。我如何在一个地方做到这一点?我尝试将以下内容放在 styles.xml 中的 Base application theme 中:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    .....
    <item name="fontFamily">@drawable/Exo2_ExtraBold</item>
    .....
</style>

但是它只改变了MainActivityfontFamily,我猜是因为只有activity上面有Theme = "@style/AppTheme"属性。如果我将该属性放在其余活动之上,我想它也会起作用,但是没有一种更简单的方法可以实现所有应用程序在应用程序的一个位置设置一个 fontFamily 吗?我还把 .otf 文件放在 drawables 文件夹中 我试着把它放在我手动创建的 font 文件夹中,但是在尝试重建解决方案时它给了我一个错误。所以我想知道如何解决这个问题,将 .oft 放在正确的文件夹中。

当我们创建一个新的 Activity 时,它的超级 class 默认是 Activity 。所以我们应该手动将其更改为AppCompatActivity。并添加行 Theme = "@style/AppTheme"

using Android.Support.V7.App;
[Activity(Label = "Activity1", Theme = "@style/AppTheme")]
public class Activity1 : AppCompatActivity

在 android 中使用自定义字体的最简单方法是使用 Calligraphy, for Xamarin you can use CallygraphyXamarin

  1. 复制您的自定义字体,例如:my-custom-font.ttf,到 fonts 目录,在 assets 目录中。
  2. 添加CallygraphyXamarin nuget包Install-Package CallygraphyXamarin

  3. 创建一个class,例如:Startup并向其中添加以下内容:

[Application]
public class Startup : Application
{   
    public Startup(IntPtr javaReference, JniHandleOwnership transfer)
        : base(javaReference, transfer) { }

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

        CalligraphyConfig.InitDefault(
            new CalligraphyConfig.Builder()
                .SetDefaultFontPath("fonts/my-custom-font.ttf")
                .SetFontAttrId(Resource.Attribute.fontPath)
                .Build()
        );      
    }
}
  1. 在您的 Activities 中添加以下代码,您就可以开始了。
protected override void AttachBaseContext(Context context)
{
    base.AttachBaseContext(Calligraphy.CalligraphyContextWrapper.Wrap(context));
}

您可以创建一个基础 activity 以避免将上述代码添加到每个 activity.

更新:

为了改变工具栏的字体,如果你不想添加 Textview 作为它的标题,你应该添加以下样式到 style.xml

<style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
    <item name="fontPath">fonts/custom-font.ttf</item>
</style>

并将此样式应用到工具栏,如下所示:

<android.support.v7.widget.Toolbar
    ...
    android:theme="@style/ToolbarTheme"/>

Related github issue

这是我的 MainActivity :

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : AppCompatActivity
{
    Button informationBtn;
    ImageButton congressImageBtn;
    ImageButton exhibitionAreaImageBtn;
    ImageButton facebookImageBtn;
    ImageButton twitterImageBtn;
    ImageButton linkedinImageBtn;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.MainActivity);

        FindViews();

        BindClickEvents();

    }

    /// <summary>
    /// Method to find the views
    /// </summary>
    private void FindViews()
    {
        informationBtn = FindViewById<Button>(Resource.Id.informationBtn);
        congressImageBtn = FindViewById<ImageButton>(Resource.Id.congressImageBtn);
        exhibitionAreaImageBtn = FindViewById<ImageButton>(Resource.Id.exhibitionAreaImageBtn);
        facebookImageBtn = FindViewById<ImageButton>(Resource.Id.facebookImageBtn);
        twitterImageBtn = FindViewById<ImageButton>(Resource.Id.twitterImageBtn);
        linkedinImageBtn = FindViewById<ImageButton>(Resource.Id.linkedinImageBtn);
    }

    /// <summary>
    /// Method to bind the click events
    /// </summary>
    private void BindClickEvents()
    {
        informationBtn.Click += delegate
        {
            StartActivity(typeof(ContactInformationActivity));
            Finish();
        };

        congressImageBtn.Click += delegate
        {
            StartActivity(typeof(CongressActivity));
            Finish();
        };

        exhibitionAreaImageBtn.Click += delegate
        {
            StartActivity(typeof(ExhibitionAreaActivity));
            Finish();
        };

        facebookImageBtn.Click += delegate
        {
            var uri = Android.Net.Uri.Parse("https://www.facebook.com/");
            var intent = new Intent(Intent.ActionView, uri);
            StartActivity(intent);
        };

        twitterImageBtn.Click += delegate
        {
            var uri = Android.Net.Uri.Parse("https://twitter.com/");
            var intent = new Intent(Intent.ActionView, uri);
            StartActivity(intent);
        };

        linkedinImageBtn.Click += delegate
        {
            var uri = Android.Net.Uri.Parse("https://www.linkedin.com/");
            var intent = new Intent(Intent.ActionView, uri);
            StartActivity(intent);
        };
    }

    protected override void AttachBaseContext(Context context)
    {
        base.AttachBaseContext(Calligraphy.Xamarin.CalligraphyContextWrapper.Wrap(context));
    }

}