ComponentOne Information

ComponentOne Studio/Wijmo/Xuniの最新情報を公開中

Xamarin.Formsでカスタムフォントを利用したアイコンを表示する

アイコンとは視覚的に操作が直感的にわかりやすいように、小さく図案化したものです。 各種アプリケーションで利用されているのでいまさら説明するまでもありません。

最近では「保存」を意味するアイコンが、本当にその形で良いのか?という疑問もありますが、 可能な限り多くの人に、わかりやすい形でデファクトスタンダードの方式で一般的なものが使われています。

アイコンを表示するためには、アイコン用の画像ファイルを利用するのが一般的でしたが、昨今ではアイコンを文字として定義し、その文字に対応したフォントでそれぞれのアイコンを示すこともあり、 フォントによるWebページやアプリ制作の現場で利用されています。

有名なのはFontAwesomeです。

Ver.4.7.0(2017年2月現在)では、675個のアイコンがフォントとして提供されています。
一般的なアイコンだけにとどまらず、著名企業やサービスのブランドロゴも含まれます。

これらはXamarinで開発するアプリでも利用可能です。
この記事では、このフォント「FontAwesome」をXamarin.Fomrsアプリで利用する手順を解説します。 Xuni(ズーニー)のコンポーネントであるFlexChartで表示したグラフのX軸ラベルに、おなじみのブランドアイコンを表示します。

フォントの配布
今回はアプリの配布は行いませんが、FontAwesomeはオープンフォントライセンスなのでアプリにフォントを添付できます。
“FontAwesome” is lisenced under the SIL Open Font License 1.1
SIL Open Font License


サンプルプロジェクトの作成

Xamarin.Formsを利用し、C#でAndroid、iOSのサンプルアプリを作成します。
Xuniでチャートを表示するアプリです。手順は以下になります。

  1. Xamarin.Formsのプロジェクトを作成
  2. Xuniを利用する設定
  3. フォントファイルをプロジェクトに組み込む
  4. 表示用データを作成するクラスを作成
  5. 表示する画面の設定

1と2の説明は省略します。すでにXuniの利用準備が整っているプロジェクトを公開していますので、これを改造して利用します。プロジェクトは以下からダウンロード可能です。

フォントをプロジェクトに組み込む

FontAwesomeは前述のWebサイトで公開されていますので、ダウンロードして利用できます。 ダウンロードしたファイルFontAwesome.otfは、Android/iOSそれぞれのプロジェクトに保存してください。

それぞれの保存先は以下です。 また、各ファイルのプロパティも設定します。通常はファイルを追加した時点でこの設定になっています。

プロジェクト ファイル保存先 プロパティ設定
Android Assets/Fonts ビルドアクション:AndroidAsset
出力ディレクトリにコピー:コピーしない
iOS Resources/Fonts ビルドアクション:BundleResource
出力ディレクトリにコピー:コピーしない

iOSプロジェクトの設定

次に各プロジェクトからフォントを利用する設定です。
iOSでは、前述の場所にフォントファイルを格納し、フォントの利用をinfo.plistに記載するだけです。

info.plistの指定

今回はVisual Studio for Macを利用します。

f:id:ComponentOne_JP:20170221155823p:plain

  1. Visual Studio for Mac でinfo.plistを開いて[ソース]のタブを選択
  2. 「新しいエントリの追加」をクリックして、ドロップダウンからFonts provided by applicationを選択
  3. 文字列にフォントファイルを保存したResources以下のパスFonts/FontAwesome.otfを記述

f:id:ComponentOne_JP:20170221155719p:plain

Xamarin Studioでも同じ作業が可能ですがVisual Studioの場合はIDE画面での設定ができません。XMLファイルとして直接編集して以下の内容を追記してください。

<plist version="1.0">
  <dict>
       : 省略 
    <key>UIAppFonts</key>
    <array>
        <string>Fonts/FontAwesome.otf</string>
    </array>
</dict>
</plist>

Androidプロジェクトの設定

Androidは特に指定する必要はありません。
しかし、そのため設定したフォントをコードで指定しても、追加したフォントの場合は適用してもらえず表示されません。
プラットフォーム固有の機能を追加して、Androidアプリにフォントの設定を追加をする必要があります。

Webサイトのナレッジベース
iOSアプリの入力領域を角丸の枠線で囲む方法 (Xamarin.Forms)
で利用したEffects機能で、Androidアプリのみに適用する設定を追加します。

Effectsの作成
  1. Androidプロジェクトに、新たにFontEffect.csクラスファイルを追加します。
  2. 作成したEffectを参照するためのassembuly属性を以下のように記述します。
[assembly: ResolutionGroupName("Effects")]
[assembly: ExportEffect(typeof(FontEffect), "FontEffect")]

3.PlatformsEffect クラスを継承し、OnAttachedメソッドをオーバーライドします。
4.FlexChaertコントロールに対して、指定したフォントからTypeFaceを作成して設定します。

上記を記述したC#のコードです。

using System;
using Android.Graphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xuni_QuickStart.Droid;
using Com.GrapeCity.Xuni.FlexChart;

[assembly: ResolutionGroupName("Effects")]
[assembly: ExportEffect(typeof(FontEffect), "FontEffect")]
namespace Xuni_QuickStart.Droid
{
 public class FontEffect : PlatformEffect
 {
    protected override void OnAttached()
    {
        // FlexChart に特化した設定
        if (Control.GetType().Equals(typeof(Com.GrapeCity.Xuni.FlexChart.FlexChart)))
        {
            // フォント格納場所のパス
            var fontPath = "Fonts/FontAwesome.otf";
            // FlexChartにキャスト
            var flexChart = (FlexChart)Control;
            // Assetsに設置したフォントファイルからTypeFaceを作成して設定
            flexChart.AxisX.LabelFontTypeface = Typeface.CreateFromAsset(Forms.Context.Assets, fontPath);        }
    }
    protected override void OnDetached()
    {
        //処理は省略
    }
 }
}

フォントの指定

フォントは共有ライブラリ(PCL)で設定します。
今回フォントを指定する対象はチャートのX軸に表示されるラベルです。
ラベルに冒頭のようなブランドロゴを設定します。

サンプルデータの作成

チャートを表示するためのサンプルデータを作成します。
ここでは、一つの要素に対して乱数で発生させた数値を組み合わせて一つのデータにしています。 データを生成するコードは以下です。 文字コードで指定している部分は、FontAwesomeのコードです。
FontAwesomeの一覧表から、各ロゴに対応する文字コードを選択しました。 現状は文字コードで記述していますが、表示時はこれが各種ロゴとしてチャートに表示されます。

// データソースを作成するクラス FlexChartのBindingContextに設定
public class FontAwesomeData
{
    private List<dataModel> appData;
    // データリストを取得するプロパティ
    public List<dataModel> Data
    {   get { return appData; }     }

    public FontAwesomeData()
    {
        Random rnd = new Random();
        appData = new List<dataModel>();
        // ブランドロゴ表示用のコード
        var LogoNames = "\uf179, \uf17b, \uf17a, \uf113, \uf293, \uf099, \uf230, \uf270, \uf1a0, \uf167".Split(',');
        for (int i = 0; i < LogoNames.Length; i++)
        {
            // ロゴと乱数で発生させた数値をデータとしてリストに格納
            var dm = new dataModel();
            dm.Logo = LogoNames[i].ToString();
            dm.NumData = rnd.Next(60, 100);
            appData.Add(dm);
        }
    }
}
// データモデル
public class dataModel
{
    public string Logo { get; set; }  // ロゴ
    public int NumData{ get; set; }  // サンプルデータの数値
}

FlexChartの設定

チャートを表示するための設定を行います。
画面用のXAMLには、チャートを表示するためのchartStacklayoutに入れています。
また、データを表示するための系列(Series)を定義し、データソースのNumDataBindingしています

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="Xuni_QuickStart.Xuni_QuickStartPage"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Xuni_QuickStart"
             xmlns:xuni="clr-namespace:Xuni.Forms.FlexChart;assembly=Xuni.Forms.FlexChart">

    <StackLayout VerticalOptions="FillAndExpand" 
                 Orientation="Vertical" 
                 Padding="0,20,0,20">
        <xuni:FlexChart x:Name="chart"
                        BindingX="Logo"
                        ItemsSource="{Binding Data}"
                        VerticalOptions="FillAndExpand">
            <xuni:FlexChart.Series>
                <xuni:ChartSeries 
                        x:Name ="S1"
                        Binding="NumData" 
                        Color  ="#b50f52"/>
            </xuni:FlexChart.Series>
        </xuni:FlexChart>
    </StackLayout>
</ContentPage>

コードビハインドでFlexChartの設定を行います。

  1. データソースをBindingContextに設定
  2. チャートの種類を曲線面チャート(SprineArea)に設定
  3. チャートのX軸の設定 ここでAndroid、iOSのプラットフォームを判断して、設定を変えます。
    Androidの場合: こちらで作成したEffectを適用
    iOSの場合:X軸のラベル用フォントをLabelFontFamilyプロパティに指定
  4. Y軸の設定 最大値、最小値そして目盛りの幅の単位を指定
public partial class Xuni_QuickStartPage : ContentPage
{
    public Xuni_QuickStartPage()
    {
        InitializeComponent();
        // データソースをFlexChartにバインディング
        chart.BindingContext = new FontAwesomeData();
        // チャート種類を曲線面チャートに設定
        chart.ChartType = Xuni.Forms.FlexChart.ChartType.SplineArea;
        // チャートのX軸の設定
        chart.AxisX.LabelFontSize = 30;

        // プラットフォームを判定して処理を分割
        if (Device.OS == TargetPlatform.Android)
        {
            // Androidプロジェクトに作成したEffectsを適用
            // X軸のラベルにフォントが適用される
            chart.Effects.Add(Effect.Resolve("Effects.FontEffect"));
        }
        else if(Device.OS == TargetPlatform.iOS)
        {
            // iOSの場合はResourceに追加したフォントを
            // infpo.plist に追加指定すると利用可能になり適用される
            chart.AxisX.LabelFontFamily = "FontAwesome";
        }

        // チャートのY軸の設定
        chart.AxisY.MajorUnit = 10;
        chart.AxisY.Min = 50;
        chart.AxisY.Max = 100;
    }
}

ブランドロゴを表示

実行した結果が以下の画像です。データの名称部分、つまりX軸のラベルに設定された文字コードが、フォントを利用した表示になり、ブランドロゴになりました。

f:id:ComponentOne_JP:20170221155454p:plain

今回利用したすべてのブランドアイコンはそれぞれの所有者の商標です。  
また、アイコンはすべてそのブランドを意味していますが、チャート上のデータはランダムな数値を利用しており、
アイコンおよび各ブランドとの関連はありません。  

まとめ

このように、カスタムフォントを組み込むことで、アプリ画面のデザインが変わるだけでなく、ユーザー操作を促すことができます。FontAwesomeで提供されるアイコンを駆使してインタラクションの優れたアプリ開発が実現できます。

なお、フォントの埋め込みには各フォントで決められています。フォントの配布が許可されているフォントであれば、今回の例のようにアプリに埋め込んで利用できます。それぞれの利用条件を確認してご利用ください。


参考情報

Xamarin Formsでアイコンフォントを表示する - yamamoWorks

jamesmontemagno/XamDroid.RobotoText: Roboto text everywhere!

ComponentOne