📚

XMLベースのコードをJetpack Composeに移行する方法 1-AndroidView~旧来のカスタムViewの利用

2022/04/18に公開

概要

Jetpack ComposeはXMLベースで記述されている旧来のコードを少しづつ移行する方法を提供しています。

それがAndroidViewComposeViewです。
この記事では、AndroidViewのついて記述します。
これは、旧来の方法で作成したコードベースのビュークラスをJetpack Composeで利用する方法です。

AndroidView

Jetpack Composeでは、従来のAndroidレイアウトやビューをコンポーザブル関数内で自然に利用することができます。

つまり、旧来の実装で作成したカスタムビューをJetpack Composeの中で使えるという事です。

たとえば、以下のカスタムビューがあったとします。これはボタンを押下するとボタンのテキストの数字がカウントアップするビューです。

class CountUpButton @JvmOverloads constructor(
  context: Context,
  attrs: AttributeSet? = null,
  defStyleAttr: Int = R.attr.buttonStyle
) : androidx.appcompat.widget.AppCompatButton(context, attrs, defStyleAttr),
  View.OnClickListener {

  private var count = 0;

  init {
    setOnClickListener(this)
    text = "Count Up $count"
  }

  override fun onClick(v: View?) {
    count++
    text = "Count Up $count"
  }
}

ちなみに旧来のxmlだったら以下のように利用していました

        <com.ko2ic.spike.migrate.compose.ui.view.CountUpButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:textAllCaps="false"/>

このカスタムビューをJetpack Composeで利用する方法です。それは以下です。

  @Composable
  fun CountUpButtonView() {
    AndroidView(
      factory = ::CountUpButton,
    )
  }

これだけです。AndroidViewコンポーザブル関数のfactoryに対象のカスタムビューのインスタンスを渡します。

AndroidViewコンポーザブル関数のインターフェイスは以下の通りです。

@Composable
fun <T : View> AndroidView(
    factory: (Context) -> T,
    modifier: Modifier = Modifier,
    update: (T) -> Unit = NoOpUpdate
)

引数のupdateは、layoutがinfalateされた後に呼ばれるコールバックメソッドです。

updateの使い方として、わかりやすい例として、たとえば、WebViewがあります。
WebViewはJetpack Composeで用意されていません。
これを以下のようにすれば利用できます。

AndroidView(
    factory = ::WebView,
    update = { webView ->
        webView.webViewClient = WebViewClient()
        webView.loadUrl(url)
    }
)

このようにすることでJetpack Composeで用意されていないクラスを利用することができるのです。
簡単ですね。

まとめ

XMLベースで利用してきたコードを簡単にJetpack Composeで利用できることがわかりました。
これにより、少しづつJetpack Composeへの移行ができます。

また、それよりも重要なこととして、新しい技術を使うときに必要になるのは、逃げ道があるかどうかです。
Jetpack Composeでどうしても実装が難しいときに、AndroidViewを使うことで既存のコードを使い実装することができます。
これはJetpack Composeを本番プロダクトで利用するときに大きな安心感をもたらすことになるでしょう。

NewsPicks の Zenn

Discussion