XMLベースのコードをJetpack Composeに移行する方法 1-AndroidView~旧来のカスタムViewの利用
概要
Jetpack ComposeはXMLベースで記述されている旧来のコードを少しづつ移行する方法を提供しています。
それがAndroidView
とComposeView
です。
この記事では、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 メンバーの発信を集約しています。公式テックブログはこちら→ tech.uzabase.com/archive/category/NewsPicks
Discussion