1
votes

I'm working on a multiplatform app with Xamarin.Forms for Android, iOS and UWP. One of the requirements is to apply a corporate custom font on the title of all pages, which are instances of NavigationPage. I've got this working for iOS but I can't get it to work for Android or UWP. What I've done is to create custom renderers for each platform. For iOS this is working with the following code:

using System.ComponentModel;
using UIKit;
using MyNameSpace.iOS.Renderers
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRendererAttribute(typeof(NavigationPage), typeof(MyNavigationPageRenderer))]
namespace MyNameSpace.iOS.Renderers
{
    public class MyNavigationPageRenderer : NavigationRenderer
    {
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            var page = this.Element as NavigationPage;
            if (page == null) return;

            this.NavigationBar.TitleTextAttributes = new UIStringAttributes
            {
                Font = UIFont.FromName("MyFont", 18),
                ForegroundColor = page.BarTextColor.ToUIColor()
            };
        }
    }
}

I know how to get the correct font in the OnElementChanged-method for the Android and the UWP platform but how do I apply them? I can't find a property to set.

1
Have you attempted translating something like this to Xamarin? stackoverflow.com/questions/8607707/…Timothy James
Thanks @timothy, you made me realize that I indeed had to dive into native Android. I've found a working solution for Android and partially answered the question myself.Robin Dijkstra

1 Answers

4
votes

I can partially answer my own question. For Android, there are a lot of solutions in Java and translating them to Xamarin is not always easy. But I have found a reasonable and easy to understand solution, based on Getting ActionBar Title TextView with AppCompat v7 r21.

First, add a TextView to Resources/layout/toolbar.axml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_scrollFlags="scroll|enterAlways">

  <TextView
        style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Toolbar Title"
        android:gravity="center_vertical"
        android:id="@+id/toolbar_title" />

</android.support.v7.widget.Toolbar>

Then create a custom NavigationPage renderer:

using System;
using System.ComponentModel;
using Android.Graphics;
using Android.Widget;
using MyNameSpace.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using Support = Android.Support.V7.Widget;


[assembly: ExportRenderer(typeof(NavigationPage), typeof(MyNavigationPageRenderer))]
namespace MyNameSpace.Droid.Renderers
{
    public class MyNavigationPageRenderer : NavigationPageRenderer
    {
        private Support.Toolbar _toolbar;

        public override void OnViewAdded(Android.Views.View child)
        {
            base.OnViewAdded(child);

            if (child.GetType() == typeof(Support.Toolbar))
                _toolbar = (Support.Toolbar)child;
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            var page = this.Element as NavigationPage;

            if (page != null && _toolbar != null)
            {
                Typeface tf = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, "MyFont.ttf");

                TextView title = (TextView)_toolbar.FindViewById(Resource.Id.toolbar_title);
                title.SetText(page.CurrentPage.Title, TextView.BufferType.Normal);
                title.SetTypeface(tf, TypefaceStyle.Normal);
            }

        }

    }
}

In the OnViewAdded-event, we get a reference to the toolbar. In the OnElementPropertyChanged-event, we get the custom font from the assets and with a FindViewById() we retrieve the defined TextView. Then we can set the Title and Typeface (font) of the Textview of the Toolbar.

So far so good. Anyone an idea to accomplish the same in the UWP-project?