【Kotlin】冗長的なレイアウトファイルからの脱却

アンケート画面などで複数のTextViewやCheckBoxが繰り返し表示される画面を作成するときレイアウトファイル(.xml)が冗長的になってしまうことがあるかと思います。
以下の画像のようなチェックボックスが複数個並んだViewを作成するとします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484337/6d57496e-4890-652b-c2db-c7b88e88541a.jpeg" width=50%>

この時のレイアウトファイルとして真っ先に考えられるのはこんな感じかなっと思います。

```.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <CheckBox
                android:id="@+id/checkBox1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目1" />

            <CheckBox
                android:id="@+id/checkBox2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目2" />

            <CheckBox
                android:id="@+id/checkBox3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目3" />

            <CheckBox
                android:id="@+id/checkBox4"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目4" />

            <CheckBox
                android:id="@+id/checkBox5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目5" />

            <CheckBox
                android:id="@+id/checkBox6"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="チェック項目6" />
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>


```

この記事ではこのような冗長的なレイアウトファイル（CheckBoxが描画したい数だけレイアウトファイルに繰り返されている）から脱却する実装方法を紹介します。
例でチェックボックスを扱っていますがTextViewやImageViewでも同様に実装できます。

## 描画するCheckboxのenum classを作成
最初に描画するチェックボックスをそれぞれ`enum`で定義します。

```CheckboxList.kt
// isCheckはデフォルトでチェックをつけるかのフラグ
enum class CheckboxList(@StringRes val title: Int, val isCheck: Boolean) {
    FIRST(R.string.checkbox1, true),
    SECOND(R.string.checkbox2, false),
    THIRD(R.string.checkbox3, false),
    FORTH(R.string.checkbox4, false),
    FIFTH(R.string.checkbox5, true);
}
```
## .ktファイルで実装する

CheckBoxやTextViewなどはActivityやFragmentの中でも生成することができるので、そちらを利用します。
※DataBindingを使用します。

```.MainActivity.kt
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        createCheckBox()
    }

    private fun createCheckBox() {
        /**
         * CheckboxListに定義されている要素の数だけ繰り返す。
         */
        CheckboxList.values().forEachIndexed { index, checkboxList ->
            val checkbox = Checkbox(requireContext())  // Checkboxインスタンスの生成

            checkbox.apply {
                id = index // チェックボックスのリソースIDを設定（今回は0~4)
                text = requireContext().resources.getText(checkboxList.title) // enumに定義されたタイトルをセット
                isCheck = checkboxList.isCheck
            }
            binding.linearView.addView(checkbox) // linearView(LinearLayout)にcheckboxを追加
        }
    }
```

```Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">

        <LinearLayout
            android:id="@+id/linear_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
        </LinearLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

```

このようにコードベースで実装することで冗長的なレイアウトファイルから脱却できます。
また、チェックボックスが追加になった場合でも`enum`に要素を追加すればいいため修正コストも下がると思います。

今回はチェックボックスで実装しましたが、TextViewやButton、ImageViewでもできると思うので冗長的なレイアウトになりそうな時はこちらの手法も考えて見てはいかがでしょうか？