Androidアプリ開発のうち、気配りが重要な工程といえば「小さいエリア内での文字フォントサイズ指定」が、そのひとつに挙げられます。
一般的には「ピクセル単位」でフォントサイズをデザインされると見受けられますが、習慣的に「スケーラブルピクセル(sp)」を指定していると、ユーザーが設定アプリでフォントサイズを大きめにしていた場合、以下のような不具合が発生します。
![]() | ![]() |
最大では、領域不足で文字やアイコンが一部見えなくなってしまいました。
ここでは以下の3つの解決方法を挙げていきます。
TextViewの自動サイズ調整
Android 8.0(API Level 26)から追加された、ビューから見切れないように自動的にフォントサイズを合わせてくれる機能です。
(下位互換クラス:TextViewCompat)
<TextView
android:id="@+id/text_you_parcent"
android:layout_width="54dp"
android:layout_height="41dp"
android:layout_marginEnd="6dp"
android:ellipsize="none"
android:gravity="end|bottom"
android:includeFontPadding="false"
android:singleLine="true"
android:text="100"
android:textColor="@color/orange"
android:textStyle="bold"
app:autoSizeMaxTextSize="28sp"
app:autoSizeMinTextSize="8sp"
app:autoSizeTextType="uniform"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/unit_you_percent"
app:layout_constraintStart_toEndOf="@id/icon_you"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
![]() ![]() | ![]() ![]() |
アイコン付近の文字とパーセント値にautoSizeを適用。ビューエリアの範囲で拡大縮小されます。
一見便利ですが、注意点もあります。
- wrap_content が機能しない(使った場合、表示結果が保証されない)
- app:layout_constraintBaseline_toBaselineOf の制約が機能しない(%などの単位とbottomを揃えられない)
SmallestWidthなどの代替リソースを提供
例えば「layout-sw600dp」のようにリソースディレクトリを追加して、600dp未満の端末はデフォルトの「layout」ディレクトリにあるフォントサイズを小さめに設定したリソースを参照させる方法です。
<!-- 480dpi以上のフォントサイズ指定 -->
<resources>
<dimen name="wz_percent_size">28sp</dimen>
<dimen name="wz_caption_size">10sp</dimen>
<dimen name="wz_name_size">16sp</dimen>
</resources>
<!-- 480dpi未満のフォントサイズ指定 -->
<resources>
<dimen name="wz_percent_size">17sp</dimen>
<dimen name="wz_caption_size">6sp</dimen>
<dimen name="wz_name_size">10sp</dimen>
</resources>
<TextView
android:id="@+id/text_you_parcent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:gravity="end"
android:includeFontPadding="false"
android:singleLine="true"
android:text="100"
android:textColor="@color/orange"
android:textSize="@dimen/wz_percent_size"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@id/unit_you_percent"
app:layout_constraintEnd_toStartOf="@id/unit_you_percent"
app:layout_constraintStart_toEndOf="@id/icon_you" />
![]() | ![]() |
アイコン付近の文字とパーセント値のフォントサイズをsmallestWidthごとに分けました。
幅360dpの端末なので、デフォルトのdimens.xmlが使われます。
注意点としては、以下のようなものでしょうか。
- リソースファイルが増えるので、その分レイアウト変更時の開発&テスト工数が増える
- 大ざっぱに分けた場合、中間の幅の端末で中途半端な大きさで表示されるおそれがある
密度非依存ピクセルを指定
要は「android:textSize属性にdp単位で指定する」ということですが、
先に注意点として挙げますと、以下のような限定されたケースに対して使用するべきでしょうか。
- 「アイコンの補足」といったような、優先度が高くない文言
- もともと大きめにフォントサイズ指定された改行しない数字など
<TextView
android:id="@+id/text_you_parcent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:gravity="end"
android:includeFontPadding="false"
android:singleLine="true"
android:text="100"
android:textColor="@color/orange"
android:textSize="28dp"
android:textStyle="bold"
app:layout_constraintBaseline_toBaselineOf="@id/unit_you_percent"
app:layout_constraintEnd_toStartOf="@id/unit_you_percent"
app:layout_constraintStart_toEndOf="@id/icon_you"
tools:ignore="SpUsage" />
![]() | ![]() |
アイコン付近の文字とパーセント値のフォントサイズを密度非依存ピクセルで指定。
Android Studioで警告がでないように tools:ignore=”SpUsage” を追加しています。
「sp と dp を間違えた」と思われないように、コメントで補足する必要があるかもしれません。
まとめ
AutoSizeも加わって、Androidのテキスト界隈もだいぶ使い勝手がよくなってきたと感じられます。
それぞれのメリットと注意点を踏まえて、スマホアプリのアクセシビリティを高めていきたいと思いました。