FC2ブログ

記事一覧

ImageCell にカスタムフォントを表示させる方法 | Xamarin.Forms


今回は Xamarin.Forms で ImageCell コントロールに カスタムフォント(独自フォント)を利用してアプリに表示させる方法についてご紹介いたします。通常のラベルやボタンにカスタムフォントを適用する方法については以前の記事でもご紹介していますが、ImageCell へのフォントの反映方法は少し工夫が必要でした。

そもそも ImageCell ではなく、ViewCell を ListView に適用していれば、以前の記事で作成していたレンダラーでカスタムフォントが適用されますが、ImageCell には、iOS では標準の UILabel 、Android では標準の TextView が適用されるため、作成したカスタムレンダラーの適用対象外となっていました。


iOS
xamarin_imagecell_renderer_01.png
Andorid
xamarin_imagecell_renderer_02.png

※Androidで文字の色が変わっていますが、全体にテーマスタイルが適用されている為です。


前提条件
・Windows10 Pro 64Bit 1803
・Visual Studio 2017 Community
・Xamarin 4.11.0.776 (NuGet Xamarin.Forms 2.4.0.282)
・macOS Mojave 10.14 / Xcode10.1 / Xamarin.iOS 12.0.0.10



1.事前準備

以前の記事でもご紹介していますが、以下の項目については設定を済ませておくことが前提です。
・必要なフォントのダウンロード
・各プロジェクトへの配置
・Info.plist の設定
・PostScript名の取得



2.派生コントロールの実装

PCLプロジェクト内に ImageCell を継承した派生コントロールを作成します。
独自のプロパティを用意して、フォント名を保持できるように機能拡張しています。

BaseImageCell.cs
using Xamarin.Forms;
namespace AppName.Controls
{
public class BaseImageCell : ImageCell
{
public BaseImageCell() : base()
{
}

public static readonly BindableProperty FontFamilyProperty =
BindableProperty.Create("FontFamily",
typeof(string),
typeof(BaseImageCell),
Font.Default.FontFamily);

public string FontFamily
{
get { return (string)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
}
}



3.Androidの実装方法

Android プロジェクトに以下のファイルを作成します。
PCL で実装した派生コントロールに付け加えたプロパティからフォント名称を取得し、各ラベルにフォントを設定しています。
ただし、Typeface.CreateFromAsset の処理が非常に重く、コントロールを多く表示する画面では UI の更新をブロックしてしまう為、使いまわすように実装しています。個々のコントロールでフォントが異なる場合は使いまわせません。

CustomImageCellRenderer.cs
using System;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Graphics;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using AppName.Droid.Renderer;
using AppName.Controls;
[assembly: ExportRenderer(typeof(BaseImageCell), typeof(CustomImageCellRenderer))]
namespace AppName.Droid.Renderer
{
public class CustomImageCellRenderer : ImageCellRenderer
{
//Fontを使いまわす為
private static Typeface _font = null;

protected override global::Android.Views.View GetCellCore(Cell item, global::Android.Views.View convertView, ViewGroup parent, Context context)
{
var cell = (BaseCellView)base.GetCellCore(item, convertView, parent, context);
if (cell != null)
{
//ImageCellの内部のTextViewを取得する
var linear = (LinearLayout)cell.GetChildAt(1);
var label = (TextView)linear.GetChildAt(0);

//BaseImageCellのカスタムプロパティに設定されたフォント名を取得する
var imageCell = (BaseImageCell)item;
string fontName = imageCell.FontFamily;

//フォントを設定する
if (_font == null)
{
_font = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, fontName);
}
label.SetText(imageCell.Text, TextView.BufferType.Normal);
label.SetTypeface(_font, TypefaceStyle.Normal);
}
return cell;
}
}
}



4.iOSの実装方法

iOS プロジェクトに以下のファイルを作成します。Android と同様に PCL で実装した派生コントロールに付け加えたプロパティからフォント名称を取得し、各ラベルにフォントを設定しています。

CustomImageCellRenderer.cs
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using AppName.iOS.Renderer;
using AppName.Library.Utility;
using AppName.Controls;
[assembly: ExportRenderer(typeof(BaseImageCell), typeof(CustomImageCellRenderer))]
namespace AppName.iOS.Renderer
{
public class CustomImageCellRenderer : ImageCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
if (cell != null)
{
//BaseImageCellのカスタムプロパティに設定されたフォント名を取得する
BaseImageCell imageCell = (BaseImageCell)item;
string fontName = imageCell.FontFamily;

//フォントを設定する
UILabel label1 = cell.DetailTextLabel;
label1.Font = UIFont.FromName(fontName, label1.Font.PointSize);
UILabel label2 = cell.TextLabel;
label2.Font = UIFont.FromName(fontName, label2.Font.PointSize);

UpdateBackground(cell, item);
}
return cell;
}
}
}



5.使用方法

ListView に適用する ImageCell を今回作成した派生コントロールに変更し、そのプロパティにフォント名をセットするだけです。
以下のサンプルコードは以前の記事「MasterDetailPageの設定方法」でご紹介していたソースに加筆するものです。

MenuListView.cs
using AppName.Controls;
using Xamarin.Forms;
namespace AppName.Controls
{
public class MenuListView : ListView
{
public MenuListView()
{
this.Initialize();
}
public MenuListView(ListViewCachingStrategy strategy) : base(strategy)
{
this.Initialize();
}
public void Initialize()
{
// ListView の設定
List<MenuItem> data = new MenuListData();
ItemsSource = data;
VerticalOptions = LayoutOptions.FillAndExpand;
BackgroundColor = Color.Transparent;

// ImageCellをバインド
var cell = new DataTemplate(typeof(BaseImageCell));
cell.SetBinding(TextCell.TextProperty, "Title");
cell.SetBinding(ImageCell.ImageSourceProperty, "IconSource");
cell.SetBinding(BaseImageCell.FontFamilyProperty, "FontFamily"); //今回作成した派生コントロールのプロパティです。
ItemTemplate = cell;
}
}

/// <summary>
/// ListView のデータ用のクラスです。
/// </summary>
public class MenuItem
{
public string Title { get; set; }

public string IconSource { get; set; }

public string FontFamily
{
get
{
switch (Device.RuntimePlatform)
{
case Device.iOS:
return "Georgia-BoldItalic"; //PostScript名

case Device.Android:
return "Fonts/Georgia-BoldItalic.ttf"; //ファイル名

default:
throw new NotImplementedException("想定していないプラットフォームです。");
}
}
}
}
}



6.関連記事

ラベルやボタンにカスタムフォントを適用させる方法については以下の記事にて紹介しております。
https://itblogdsi.blog.fc2.com/blog-entry-156.html

ナビゲーションバー(タイトルの部分)のフォント・スタイル変更については以下の記事にて紹介しております。
https://itblogdsi.blog.fc2.com/blog-entry-157.html








最後までお読みいただきありがとうございます。
当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
https://itblogdsi.blog.fc2.com/blog-entry-81.html



関連記事

コメント

コメントの投稿

※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。

 入力されていないコメントには返信しませんのであらかじめご了承くださいませ。

※ニックネームでも良いので必ずご入力ください。

    

※必ずご入力ください。

    
    

※必ずご入力ください。

※技術的な質問には環境やエラーについて正確かつ詳細にお教えください。

・正確なエラーの内容

・Windowsのバージョン番号

・Visual Studioのバージョン

・機器の型番

・アプリやソフトのバージョン

    

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。