PG.Lib

アプリ開発関連とかガジェット関連とか

Xamarin.Forms Labelにカスタムフォント

各OSにビルドインなフォントだけでなく、自作やフリーなフォントを使ってデザインしたいケースがあると思います。

Labelの場合で、カスタムフォントを設定する場合を紹介したいと思います。

なお、iOSはMacが無く確認する環境がありませんので参考程度にご覧ください。

参考ドキュメント
Fonts - Xamarin


フォントファイルの配置

UWPの場合

基本どこでも良さそうですが、Assets フォルダが初期にできてたりするので、その中にわかりやすく Fonts というフォルダを作りその中に配置しました。

f:id:fxxk_authority:20170420145605p:plain

ファイルのプロパティで、ビルドアクションが コンテンツ になっていることは確認しておきます。

出力ディレクトリにコピーは コピーする 系になってたほうが良さげですが、ローカルPCでデバッグした限りではコピーしないでも大丈夫でした。

f:id:fxxk_authority:20170420145617p:plain

Androidの場合

Androidの場合、初期にできてる Assets フォルダに配置します。

f:id:fxxk_authority:20170420145630p:plain

ビルドアクションは AndroidAsset 、出力ディレクトリにコピーは コピーする 系になってる必要があるようです。

f:id:fxxk_authority:20170420145638p:plain

iOSの場合

iOSの場合、Resources フォルダに配置します。

f:id:fxxk_authority:20170420145645p:plain

ビルドアクションは BundleResource 、出力ディレクトリにコピーは コピーする 系になってる必要があるようです。

f:id:fxxk_authority:20170420145648p:plain

フォームの記述

フォントは FontFamily へ設定しますが、プラットフォーム事に読み方が変わるため、OnPlatformで記述を分けて書きます。

<Label Text="1" 
        FontSize="Large"
        TextColor="Black">
    <Label.FontFamily>
        <OnPlatform x:TypeArguments="x:String">
            <OnPlatform.iOS>FontName</OnPlatform.iOS>
            <OnPlatform.Android>FontName.TTF</OnPlatform.Android>
            <OnPlatform.WinPhone>Assets/Fonts/FontName.TTF#FontName</OnPlatform.WinPhone>
        </OnPlatform>
    </Label.FontFamily>    
</Label>
  • iOSの場合はフォント名
  • Androidの場合は、フォントファイル名
  • UWPの場合は、フォントパス名#フォント名

のような違いがあります。

カスタムレンダラー

Androidの場合は、カスタムレンダラーの実装までしないと反映されないようです。

C#で以下のようなクラスを作ります。

using System;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using Android.Graphics;

[assembly: ExportRenderer(typeof(Label), typeof(HOGE.Droid.CustomLabelRenderer))]
namespace HOGE.Droid
{
    public class CustomLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            if (string.IsNullOrEmpty(e.NewElement?.FontFamily))
            {
                return;
            }
            try
            {
                var font = Typeface.CreateFromAsset(Forms.Context.Assets, e.NewElement.FontFamily);
                Control.Typeface = font;
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex);
            }
        }
    }
}

これで出来る…はず!?

Androidの場合を調べてる中で、フォントファイル名#フォント名 という記述を見かけました。

カスタムレンダラーでFontFamilyへセットする際に、フォントファイル名である必要があるので、#フォント名を外したところ表示されたので、直接書く場合は#以降も欲しいような感じ?を受けました。

また、Xamarin.Forms Previewer にはフォント変更の反映はされませんでした。

実機では変わっていました。何かやり方があるのかもしれません…