Androidのレイアウト、バリア(barrier)の使い方

# barrierとは？
今回はAndroidのレイアウトの編集でバリア(barrier)の使い方について説明します。
例えばこんなレイアウトがあったとします。
![Screenshot_20221203_210115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/5f7f41d3-3a0b-9f3c-0f6d-3ea6d3523b95.png)
タイトル1に対して、なんかの値1
タイトル2に対して、なんかの値2
があって、これらを全部DBや設定ファイル、あるいはHTTPで他から取ってきて表示するとします。
今上の画面はタイトル1がタイトル2より長いので、タイトル1に合わせて、その右側のなんかの値１、なんかの値2の位置を決めています。

しかし、状況によってはタイトル1とタイトル2の長さが逆転する場合があります。こんな風に・・・
![Screenshot_20221203_210200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/c79eebd5-974f-280e-7ff7-a9239bc951a2.png)
タイトル1に合わせて、その右側のTextViewの位置を決めているので文字が被ってしまいます。

じゃ、タイトル2に合わせて、その右側のTextViewの位置を決めれば・・・いや、いや、状況によってタイトル1とタイトル2のどっちが長いか、都度変わります。こんな時どうするかと言うと、バリア(Barrier)を使います。
# barrierを使うとどういうレイアウトになる？垂直バリアの例
レイアウトエディタのComponetTreeで見るとこうなります。
![Screenshot_20221203_210709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/72661d6c-8586-b24f-8ae3-fdcf2fc59018.png)
Barrier(Virtical)をドラック＆ドロップでComponetTreeに追加します。そのバリアの階層構造で下にタイトル1とタイトル2を付けます。
バリアの属性で、「barrierDrection」に「end」（右端の意味）を指定します。
![Screenshot_20221203_210741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/522ef7c3-a3e4-61fa-5b07-6c892bdd0f47.png)
右側のなんかの値１、なんかの値2の左の位置をそのバリアからの相対位置にします。(app:layout_constraintStart_toEndOf)
![Screenshot_20221203_210342.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/bb7c9af9-0084-afe1-b0c6-ace05731aa48.png)
バリアの横軸はタイトル1かタイトル2のどちらかの長い方の位置になります。
その横のその右側のなんかの値１、なんかの値2はそのバリアの位置に対する相対位置になります。
上の例はタイトル1のほうが長い場合ですが、逆にタイトル2の方が長い場合は、こうなります。
![Screenshot_20221203_210413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/4a3ba04f-f2c2-e634-03c8-58862da8e8a5.png)
もう、文字がかぶることがありませんね。
LinerLayoutでお互いを囲うという手もありますが、こちらのほうが簡単です。

出来上がりのlayout xmlはこのようになります。
```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/title1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:text="タイトル１"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/title2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="40dp"
        android:text="タイトル２2222222"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title1" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="end"
        app:constraint_referenced_ids="title1,title2"
        tools:layout_editor_absoluteX="411dp" />

    <TextView
        android:id="@+id/value1"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:text="なんかの値・・・"
        app:layout_constraintStart_toEndOf="@+id/barrier1"
        app:layout_constraintTop_toTopOf="@+id/title1" />

    <TextView
        android:id="@+id/value2"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:text="なんかの値・・・"
        app:layout_constraintStart_toEndOf="@+id/barrier1"
        app:layout_constraintTop_toTopOf="@+id/title2" />

</androidx.constraintlayout.widget.ConstraintLayout>
```
これは横方向ですが、縦方向についても同じことが言えます。縦の場合は
Barrier(Horizontal)を使います。
# 水平方向のバリアの例、RecyclerViewとの組み合わせ
同じ理屈で、水平方向のバリア(Barrier(Horizontal))を説明してもあまり面白くありません。例えばこういう画面を想定します。
![Screenshot_20221203_211720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/84445f64-b570-d473-063d-b85529aee4e2.png)
ReCyclerViewがどかんと真ん中にあって、その上にEditTextが3つ並んでいます。スマホは画面が狭いので、ReCyclerViewは極力画面全体を使いたいです。でも、そのReCyclerViewに対してデータを入力する時は、その時だけ、EditTextの入力部分を表示してほしい。余計なときは隠れていて欲しい。こんな場合もバリアが使えます。

ComponetTreeですが、このようになります。
![Screenshot_20221203_211816.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/ea135341-83c5-dbe5-8c55-413d4e3370dd.png)
水平バリアの下にEditTextの3つを追加します。ここで、GroupもComponetTreeに追加して、Groupの下にもEditTextの3つを追加します。
水平バリアの「BarrierDirection」は「bottom」を指定します。
![Screenshot_20221203_211839.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/7d02e5e3-efbc-7378-9cea-dd641e005fc0.png)
RecyClerViewの上側の位置は水平バリアからの相対位置を指定します。(app:layout_constraintTop_toBottomOf)

この状態で、Groupの「Visibility」を「gone」にすると・・・
![Screenshot_20221203_211912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/91519579-7ba7-ba5f-1403-57571cf30b60.png)
EditTextの3つが非表示になりレイアウトが詰まります。RecyclerViewの上側は水平バリアからの相対位置なので、それに引っ張られてRecyclerViewの上側が伸びます。こんな風に、ほぼ全画面表示になります。
![Screenshot_20221203_211744.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/500031c5-22fa-05f9-6db2-0e50944538ed.png)
出来上がりのlayout xmlはこのようになります。
```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="textView10,textView11,textView12"
        tools:layout_editor_absoluteY="731dp" />

    <TextView
        android:id="@+id/textView10"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="56dp"
        android:layout_marginTop="16dp"
        android:text="なんかの入力１"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView11"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:text="なんかの入力3"
        app:layout_constraintStart_toStartOf="@+id/textView12"
        app:layout_constraintTop_toBottomOf="@+id/textView12" />

    <TextView
        android:id="@+id/textView12"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:text="なんかの入力2"
        app:layout_constraintStart_toStartOf="@+id/textView10"
        app:layout_constraintTop_toBottomOf="@+id/textView10" />

    <androidx.constraintlayout.widget.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:constraint_referenced_ids="textView12,textView11,textView10" />

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/barrier1" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

垂直バリアの「BarrierDirection」が「start」の場合、
水平バリアの「BarrierDirection」が「top」の場合も同じ理屈です。

# 最後に
水平バリアの使いかたは、
[AndroidでRecyclerViewの縦方向の自動拡大、縮小](https://qiita.com/cozyk100/items/76673faf45b33e2f7f63)も参考にしてください。