Montoolivo
Montoolivo

Reputation: 147

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

I want to set the fontFamily of the Toolbar's texts, Buttons, TextViews and for all the text of the Xamarin.Andrid application in general. How do I do that in a single place? I tried putting the following in the Base application theme in styles.xml :

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

But it only changed the fontFamily of the MainActivity, I guess it's because only that activity has Theme = "@style/AppTheme" attribute above it. If I put that attribute above the rest of the activities I guess it will also work, but isn't there an easier way to achieve all the app to have one fontFamily setting it in a single place of the application? And also I put the .otf file in the drawables folder I tried putting it in the font folder I created manually but it gave me an error when trying to rebuild the solution. So I'd like to know how can I fix that also, to put the .oft in the correct folder.

Upvotes: 1

Views: 998

Answers (3)

Mehdi Dehghani
Mehdi Dehghani

Reputation: 11601

The easiest way to use custom font in android is using Calligraphy, for Xamarin you can use CallygraphyXamarin.

  1. Copy your custom font, e.g: my-custom-font.ttf, to fonts directory, inside assets directory.
  2. Add CallygraphyXamarin nuget package Install-Package CallygraphyXamarin

  3. Create a class, e.g: Startup and add following content to it:

[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. In your Activities add following code and you are good to go.
protected override void AttachBaseContext(Context context)
{
    base.AttachBaseContext(Calligraphy.CalligraphyContextWrapper.Wrap(context));
}

You can create a base activity to avoid adding above code to each activity.

Update:

In order to change the toolbar's font and if you don't want to add Textview as its title, you should add following style to style.xml

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

And apply this style to toolbar like this:

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

Related github issue

Upvotes: 2

Montoolivo
Montoolivo

Reputation: 147

Here is my 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));
    }

}

Upvotes: 0

Lucas Zhang
Lucas Zhang

Reputation: 18861

When we create a new Activity , the super class of it is Activity in default . So we should change it to AppCompatActivity manually . And add the line Theme = "@style/AppTheme"

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

Upvotes: 0

Related Questions