［Android］TextView の文字の大きさを自動的に調整する（Autosizing TextViews）

# はじめに

Android の TextView では View サイズに応じて、
文字の大きさ(TextSize)を自動的に調整する機能が実装されています。
その機能について調べたので、簡単に使い方をまとめたいと思います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/6cc15948-9343-985d-1968-b3502c9e0683.gif" height=700px>

# View サイズに応じて TextSize を自動的に調整する

次のように TextView の autoSizeTextType を uniform に設定すると、
TextView の View サイズに応じて　TextSize が自動的に調整されるようになります。

```xml:activity_main.xml
        <TextView
            android:id="@+id/size_type_uniform_view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:text="Uniform"
            android:background="#aaffaa"
            app:autoSizeTextType="uniform"/>
```

次のような感じで View サイズの変化に応じて TextSize を自動的に調整してくれます。

![ezgif.com-rotate.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/8ee30e1d-e663-8b3d-392f-c0e3179f7631.gif)


# TextSize を大きくするステップ数の調整をする

次のように autoSizeStepGranularity を設定すると、
TextSize を大きくするステップ数の調整ができます。

```xml:activity_main.xml
        <TextView
            android:id="@+id/granularity_view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:text="Granularity"
            android:background="#aaffaa"
            app:autoSizeTextType="uniform"
            app:autoSizeStepGranularity="10dp"/>
```

次のような感じで TextSize を徐々に大きくするのではなく段階的に大きくしてくれます。

![ezgif.com-rotate (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/49d3933d-e691-0616-47ac-3622f097c791.gif)


# TextSize の最小値と最大値を調整する

次のように autoSizeMinTextSize と autoSizeMaxTextSize を設定すると、
View サイズに応じて調整される TextSize の最小値と最大値を調整できます。

```xml:activity_main.xml
        <TextView
            android:id="@+id/min_max_view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:text="MinMax"
            android:background="#ffaaaa"
            app:autoSizeTextType="uniform"
            app:autoSizeMinTextSize="25dp"
            app:autoSizeMaxTextSize="75dp"/>
```

次のような感じで、ある View サイズよりも小さくなったら TextSize が小さくならず
ある View サイズよりも大きくなったら TextSize を大きくしないようにできます。

![5dd9612db1b05307488279.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/9ab20bff-ee6f-95fb-a50b-f8bb5f975f06.gif)


# プリセットで ステップ数、最小値、最大値を定義する

autoSizeStepGranularity や autoSizeMinTextSize 、autoSizeMaxTextSize を
設定すればTextSize をどのように大きさを調整するか大まかに設定できました。

もっと詳細に調整したい場合は autoSizePresetSizes を利用します。
次のような配列（プリセット）を渡すと、TextSize をそのステップ数、最小値、最大値で調整してくれます。

```xml:arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="autosize_text_sizes">
        <item>10dp</item>
        <item>50dp</item>
        <item>100dp</item>
    </array>
</resources>
```

```xml:activity_main.xml
        <TextView
            android:id="@+id/size_preset_sizes_view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:text="PresetSizes"
            android:background="#aaaaff"
            app:autoSizeTextType="uniform"
            app:autoSizePresetSizes="@array/autosize_text_sizes"/>
```

次のような感じでプリセットのステップ数、最小値、最大値となるよう TextSize を調整してくれます。

![5dd966f85c678518635109.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/60ceaf71-350d-2a82-d244-61b4ffd814c1.gif)

# おわりに

TextView の文字の大きさを自動的に調整したいときは、
次の attributes にて どのように自動的に調整するか設定できる。

| attributes | 説明 |
| ------ | ------- |
| autoSizeTextType | uniform であれば自動的に調整する。 <br>none であれば自動的に調整しない。|
| autoSizeStepGranularity | 自動的に調整する際の TextSize を大きくするステップ数を設定する。 |
| autoSizeMinTextSize | 自動的に調整する際の TextSize の最小値を設定する。 |
| autoSizeMaxTextSize | 自動的に調整する際の TextSize の最大値を設定する。 |
| app:autoSizePresetSizes | 自動的に調整する際の プリセット を設定する。<br> プリセットに定義した内容で ステップ数、最小値、最大値が決まる | 

# 参考文献

- [Autosizing TextView Sample]([AutosizingTextViewSample](https://github.com/kaleidot725/android-mylab/tree/master/AutosizingTextViewSample))
- [Autosizing TextViews | Android Developers](https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview)