🎉

XMLベースのコードをJetpack Composeに移行する方法 2-AndroidViewBinding~旧来のXMLの利用

2022/04/19に公開

概要

前の記事では、旧来のカスタムビューをJetpack Composeで利用する方法を記述しました。

今回は、旧来のXMLレイアウトをJetpack Composeで利用する方法です。

AndroidViewBindingを利用します。

AndroidViewBinding

たとえば、こんなXMLレイアウトがあるとします。
既存の実装ではこのレイアウトを使用していて、これをJetpack Composeで使うことを想定しています。ファイル名は、xml_view_fragment.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">

    <data>
        <variable
            name="viewModel"
            type="com.ko2ic.spike.migrate.compose.ui.XmlViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/label1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="XMLのView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <TextView
            android:id="@+id/label2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@id/label1" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Jetpack Composeで上記のレイアウトを利用するコードが以下です。Databindingを利用するレイアウトファイルでしたが、ViewBindingの場合でもBindingクラスが生成されるので同様に利用できます。

class XmlViewUsageActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      XmlView()
    }
  }

  @Composable
  fun XmlView() {
    AndroidViewBinding(
      factory = XmlViewFragmentBinding::inflate,
      update = {
        label2.text = "インフレート後に設定"
      })
  }
}

ポイントは、AndroidViewBinding です。前回のAndroidViewはコードで作成した旧来のコードを利用していましたが、今回は旧来のxmlレイアウトなので、AndroidViewBindingを使っています。

AndroidViewBindingのインターフェイスは以下です。AndroidViewのインターフェイスとほぼ一緒です。

@Composable
fun <T : ViewBinding> AndroidViewBinding(
    factory: (inflater: LayoutInflater, 
              parent: ViewGroup, attachToParent: Boolean) -> T,
    modifier: Modifier = Modifier,
    update: T.() -> Unit = {}
)

まとめ

XMLレイアウトも自然にJetpack Composeで使うことができました。これで、旧来の方法で作成したカスタムビュー(前回の記事)やXMLレイアウトも無駄なく利用できます。
少しづつJetpack Composeに移行できそうです。

次回は、今までとは違うアプローチです。
旧来のコードの一部だけをJetpack Composeで実装できるComposeViewの説明をしたいと思います。

NewsPicks の Zenn

Discussion