🕶️

Flutterで英数字と日本語のTextの高さ調整

2022/07/31に公開

この記事のFlutterバージョン

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.5, on macOS 12.3.1 21E258 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] VS Code (version 1.69.2)
[✓] Connected device (4 available)
[✓] HTTP Host Availability

何が起きたか

Textを並べて表示したときに、同じ設定をしているにも関わらず、高さがズレて意図したレイアウトにならないときがありました。

英数字

iOS
iOS_英数字_英数字

Android
Android_英数字_英数字

当たり前ですが、英数字と英数字だと同じ高さになりました。

日本語&英数字

iOS
iOS_日本語&英数字

Android
Android_日本語&英数字

日本語と英数字の文字列を組み合わせると、英数字のみのTextと比べてWidgetの高さが変わってしまいます。
また、iOSとAndroidを見比べると少し文字が下にズレてしまっているようです。

頑張って自然な感じで揃えてみる

その1 Rowの並びを底辺合わせ

Rowに以下パラメータを追加して、横並びのWidgetを底辺合わせにしてみます。

crossAxisAlignment: CrossAxisAlignment.end,

iOS
iOS_Bottom_Alignment
Android
Android_Bottom_Alignment

iOSは底辺揃えにしたはずなのに、円(税込)の表示が100よりも下にずれてしまっています。
Androidも底辺揃えにはなっていますが、なぜかフォントのサイズが違うように見えてしまっています。

その2 高さを明示的に指定する

TextStyleの中にheightというパラメータがあります。これは、Textの1行の高さを指定するパラメータです。
本来であれば、気にする必要はあまりないパラメータですが、問題はheightの初期値、デフォルト値が存在しないことです。
指定方法としては、1.11.4などfontSize * height = 行の高さとなるように設定するため、今回は一行しかないため1.0を指定してみます。

    Container(
      color: Colors.yellow,
      child: const Text(
	'100',
	style: TextStyle(fontSize: 48, height: 1.0),
      ),
    ),
    Container(
      color: Colors.red,
      child: const Text(
	'円(税込)',
	style: TextStyle(fontSize: 48, height: 1.0),
      ),
    ),

iOS
iOS_textstyle_height_1

Android
Android_textstyle_height_1

まぁまぁ揃っているように見えます。だいたいの許容してもいいかもしれません。
気になる点としては、Androidのほうがまだ若干円(税込)100よりも下に突き抜けてしまっているように見えます。

その3 StrutStyleを使って調整をする

あまり使われない(と思っている)パラメータですが、今回の高さがズレる問題についてはなかなか有効なパラメータになります。
説明文を見ると、

与えられたフォントサイズ、フォントファミリー、フォントスタイルなどから想定される線の太さを計算して、行の高さを制御できるウィジェット

とのことらしいので、色々調整をしてみます。

strutStyle: StrutStyle(height: 1.5, fontSize: 48),

今回は上記のように調整してみました。(設定しているfontSizeだったりで調整値は変わります。)
iOS
iOS_structstyle
Android
Android_structstyle

個人的にはこれが正解な気がしています。

なぜiOSとAndroidでズレができるのか

結局のところ、問題としては以下2つがありました。

  1. 日本語と英数字でfontSizeが変わってしまう。
  • 原因: 日本語と英数字でフォントのベース部分が代わり、ズレが発生している
  1. iOSとAndroidでフォントが表示される部分が少しズレている。
  • 原因: OS毎にデフォルトで利用されているフォントが違う

1の問題については👆のその2の対処法で解決できると思います。
2の問題についてはプロジェクト的に問題がなければ、OS統一で一緒のフォントを利用する。もしくはその3の方法をお試しいただければ解決できると思います。

Discussion