TabLayoutの「選択されていないインジケーター」にも色を付けるには

# このTabLayoutのデザイン、どう作りますか？


![スクリーンショット 2023-06-13 21.18.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/87cad7de-22d1-1d79-d014-8b216f09df49.png)

（🚨 Composeではなく、Android Viewで実装します）

このタブのUI、みなさんならどのように実装しますか？

なんの変哲もないタブのように見えますが、よく見ると、選択していないタブにもインジケーター(というかボーダー)が付いています。

選択されていないインジケーターにはグレーのインジケーターが付いており、選択されたインジケーターにはブラックのインジケーターが付いているというデザインです。

# TabLayoutのインジケーターに好きな色を設定する方法
まず初めに、選択されているタブのインジケーターに色を設定する方法を説明します。

これは公式ドキュメントにやり方が書かれてる通りです。
[参考：TabLayout_tabIndicatorColor](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout#attr_TabLayout_tabIndicatorColor)

TabLayoutでは`tabIndicatorColor`という属性が用意されています。

![スクリーンショット 2023-06-13 22.16.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/ae4d518c-4449-9ba2-82e2-f4268be7ff91.png)

RelatedMethodに`setSelectedTabIndicatorColor(int)`と書かれてあるとおり、xml側で`tabIndicatorColor`を設定すると（おそらく）内部的に`setSelectedTabIndicatorColor`メソッドが呼ばれます。

命名からも分かる通り、選択されたTabのインジケーターの色を変更します。

```xml
 <com.google.android.material.tabs.TabLayout
    android:id="@+id/dialog_tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabIndicatorColor="@color/black"　　　// TIPS: ここでインジケーターの色を指定
    （以下略）
 />
```

# 選択されていないTabにインジケーターをつける方法
では、選択されていないTabのインジケータも同様にして色をつけることができるのでしょうか。

## ドキュメントを見てもない？！

TabLayoutで使える属性は[公式ドキュメント](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout)を開くと右端の`XML attributes`というコーナーにずらりと並んでいます。

その中でもTabのIndicatorに関係がありそうなのは赤枠の部分ですが、やりたいことができそうな属性はないようです。

![スクリーンショット 2023-06-13 22.46.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/301c14b0-df76-fa95-7984-34cde5467804.png)


## 工夫してなんとかする
Tabの下にボーダーを配置するようなdrawableを作成して、TabLayoutのbackgroundに設定します。

- xml

```xml
<com.google.android.material.tabs.TabLayout
    android:id="@+id/dialog_tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog_tab_indicator_border" // こんな感じ
    ...
/>
```


- `dialog_tab_indicator_border`

```xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-2dp" android:right="-2dp" android:left="-2dp">
        <shape>
            <solid android:color="@android:color/transparent" />
            <stroke
                android:width="2dp"
                android:color="@color/gray" />
        </shape>
    </item>
</layer-list>

```
`<shape>`タグでは図形の形を決められます。
例えば、`<shape android:shape="ring">`とすると丸い図形が描けます。今回shapeタグの中で`shape`の設定はしていませんが、デフォルトで四角形になります。なのでここで描かれる図形は四角形です。

`<solid>`は背景色を設定します。今回は`"@android:color/transparent"`なので、図形の背景色は透明です。

`<stroke>`は図形の枠線を表現します。`width="2dp"`とあるので、図形の枠線の太さは2dpです。
そして枠線の色は今回はグレーにしています。

そして最後に`<item android:top="-2dp" android:right="-2dp" android:left="-2dp">`部分です。
ここは、`layer-list`に対してpaddingを設定しています。

`<shape>`で描画した長方形は`layer-list`という入れ物に沿って作成されます。
`<item android:top="-2dp" android:right="-2dp" android:left="-2dp">`では`layer-list`と作成した四角形との間にpaddingを設定します。`"-2dp"`とあるように、負の値を設定することによって、図形の枠が`layer-list`の外側に配置されて見えなくなります。

|itemタグ内でのpaddingの設定が0dpのとき|+2dpのとき|-2dpのとき|
|---|---|---|
|<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/6371b9cb-745a-0306-9050-bcf38b726870.png">|<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/4eab8861-7bbf-5b34-d9be-4e6cd25d14c0.png">|<img width=450 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/37bc9d5b-0f97-8584-7ba6-10f18e5cd5cb.png">|
|layer-listの中ピッタリに四角形がある|layer-listより2dp内側に四角形がある|layer-listより2dp外側に枠線がでる（見えなくなる）|


今回は、`top`と`right`と`left`に負のpaddingを当てているので、上と左右の枠がなくなって長方形の下だけにボーダーが見えるようになっています。

よって、最終的には次の画像のような *背景色が透明の四角形の下にだけボーダーが表示されている図形* が描画されます。

<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/f00c9396-5e32-a0c2-d261-6802e35ad8fb.png">

（:bow: かなり分かりにくい画像ですね）

あとは先にも説明した通りこれをTabLayoutの`background`に設定して完成です〜 :clap: :tada: 

# おわり
今回は選択されていないインジケーターにも色をつける方法を解説させていただきましたが、いかがでしたでしょうか。
ポイントは負のpaddingを設定することで余分な枠を消し、四角形の底辺部分にだけボーダーを残すようなdrawableを作成したところです！

何か１つでも皆さんの日々の開発にお役に立てれば幸いに思います！