
Xamarin.Android 文字列の描画
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
今回は、Xamarin.Androidの文字列描画です。
Xamarin.Androidには、iOSのように器用なNSStringが無いので、文字列も他の図形と同じく、CanvasとPaintを使用して描画することになります。
サンプルは、ViewクラスのDraw()メソッドをオーバーライドしたものになっています。Xamarin.AndroidでViewのサブクラス化がピンとこない場合は、下記をご参照ください。
Xamarin.Android テンプレート(Blank App)
なお、描画に必要な「Paint」の扱い方は、「Xamarin.Androdi 図形(直線)の描画」で紹介したものと同じです。
2 フォント
(1) 規定のフォント
フォントの指定には、Typefaceというクラスが使用されます。 Typefaceには、いくつかの規定値があり、これらを使用すれば軽易にフォント指定ができます。
public override void Draw(Canvas canvas) {
    base.Draw(canvas);
    using (var paint = new Paint() {
                TextSize = 80,//フォントのサイズ 30pt
                Color = Color.White, //描画色(白)
                AntiAlias = true//アンチエイリアス有効
            }) {
        const string str = "Developers.IO";
       const int h = 100;
        const int x = 70;
        var y = 100;
        //デフォルトのフォント
        paint.SetTypeface(Typeface.Default);
        canvas.DrawText(str, x, y, paint);
        //太字フォント
        y += h;
        paint.SetTypeface(Typeface.DefaultBold);
        canvas.DrawText(str, x, y, paint);
        //等幅のフォント
        y += h;
        paint.SetTypeface(Typeface.Monospace);
        canvas.DrawText(str, x, y, paint);
        //ゴシック体のような「ひげ無しフォント」
        y += h;
        paint.SetTypeface(Typeface.SansSerif);
        canvas.DrawText(str, x, y, paint);
        //明朝体のような「ひげ付きフォント」
        y += h;
        paint.SetTypeface(Typeface.Serif);
        canvas.DrawText(str, x, y, paint);
    }
}
(2) フォントスタイル
太字・イタリックなどのフォントのスタイルはTypefaceStyleを使用して指定します。
TypefaceStyleは、TypefaceのCreate()の第2パラメータでセットされます。
//ノーマル paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Normal)); canvas.DrawText(str, x, y, paint); //太字 paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Bold)); canvas.DrawText(str, x, y, paint); //イタリック paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Italic)); canvas.DrawText(str, x, y, paint); //太字+イタリック paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.BoldItalic)); canvas.DrawText(str, x, y, paint);
(3) フォントファイル
TTFファイルからフォントを取得して利用することが可能です。 次のコードは、Assetsに置いた たぬきフォントのTanukiMagic.ttf を使用して文字列を描画しています。
//フォントファイル(TanukiMagic.ttf)を使用して描画する
paint.SetTypeface(Typeface.CreateFromAsset(Context.Assets, "TanukiMagic.ttf"));
canvas.DrawText("本日は晴天なり", x, y, paint);
3 属性
Androidでは、文字属性を表現するクラスはありませんが、Paintの機能によって次のような表現が可能です。
(1) 影
PaintのSetShadowLayer()で影を描画します。
var paint = new Paint {
    TextSize = 80, //文字サイズ80pt
    Color = Color.Red, //文字の色(赤)
    AntiAlias = true//アンチエイリアス有効
};
const int x = 70;
var y = 100;
//背景を白色にする
canvas.DrawColor(Color.White);
const int radius = 8;//ぼやけ具合
const int dx = 3;//元の文字からのづれ
const int dy = 3;//元の文字からのづれ
paint.SetShadowLayer(radius, dx, dy, Color.Black);
canvas.DrawText("本日は晴天なり", x, y, paint);
(2) 中抜き文字
Paint.Style.Strokeで、中抜き文字を表現できます。
var paint = new Paint {
    TextSize = 80, //文字サイズ80pt
    StrokeWidth = 2,//枠線の幅
    Color = Color.White, //文字の色(白)
    AntiAlias = true//アンチエイリアス有効
};
const int x = 70;
var y = 100;
paint.SetStyle(Paint.Style.Stroke);
canvas.DrawText("本日は晴天なり", x, y, paint);
4 パス上への描画
DrawTextOnPath()を使用すると、設定されたパスに沿った、文字列の描画が可能です。
var paint = new Paint() {
    TextSize = 60, //文字サイズ60pt
    Color = Color.Yellow, //描画色(黄)
    AntiAlias = true//アンチエイリアス有効
};
const int x = 370; //円の中心
const int y = 400; //円の中心
const int radius = 200; //円の半径
const int hOffset = 745;//表示開始のオフセット
// 円のパスを作成
var path = new Path();
path.AddCircle(x, y, radius, Path.Direction.Cw);
//パス上に文字を描画
canvas.DrawTextOnPath("本日は晴天なり", path, hOffset, 0, paint);
5 文字サイズの取得
文字列を描画する面積を取得したい場合があります。 PaintのMeasureText()を使用すれば、その時のフォントに応じた描画サイズ(ただし横幅のみ)が取得できます。
public override void Draw(Canvas canvas) {
    base.Draw(canvas);
    using (var paint = new Paint() {
               AntiAlias = true,//アンチエイリアス有効
               Color = Color.White //描画色(白)
           }) {
        const int x = 10;
        const int h = 45;
        var y = 40;
        var pt = 40;
        Disp("40ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 50;
        Disp("50ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 60;
        Disp("60ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 70;
        Disp("70ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 80;
        Disp("80ポイントの文字列", x, y += pt + h, pt, canvas, paint);
    }
}
//文字列と座標及びフォントサイズを指定して描画する
private static void Disp(string str, int x, int y, int pt, Canvas canvas, Paint paint) {
    //文字列のサイズの取得
    paint.TextSize = pt;
    //サイズの取得
    var width = paint.MeasureText(str);
    //文字列の描画
    paint.TextSize = pt;
    canvas.DrawText(str, x, y + pt, paint);
    //サイズの描画
    var s = string.Format("size:{0}", width);
    paint.TextSize = 35;
    canvas.DrawText(s, x, y, paint);
}
6 まとめ
今回は、Xamarin.Androidの文字列の描画についてまとめてみました。 iOSに比べると、表現力が豊かな気がします。 なお、こちらもXamarin.FormsでBoxViewなどのレンダラー拡張で、必要になるかもしれません。


















