Jetpack Composeの仕組みを使ってAndroid FrameworkのViewを作ってみて仕組みを知る
Jetpack ComposeはTextViewやLinearLayoutなどといったAndroid FrameworkのViewを使ってコンポーネントを描画するわけではなく、新しく作ったComponentをCanvasにdrawしています。
Jetpack ComposeはAndroidのUIの部分と木構造を扱う部分(Tree diff toolとして利用できる)としてのComposeがあり、その木構造を扱う部分の仕組みを使うことで、別のUIも作れてしまいます。 (詳しくは https://github.com/JakeWharton/mosaic/#i-thought-jetpack-compose-was-a-ui-toolkit-for-android )
例えばJetpack Compose for Web、JakeWharton/mosaicなどです。
そのため、Android FrameworkのViewを置けるようにもできます。
理解を深めるために、こんな感じのLinearLayoutとTextViewだけ置けるサンプルを作ってみました。
コード
@Composable
private fun AndroidViewApp() {
var count by remember { mutableStateOf(1) }
LinearLayout {
TextView(
text = "This is the Android TextView!!",
)
repeat(count) {
TextView(
text = "Android View!!TextView:$it $count",
onClick = {
count++
}
)
}
}
}
作って満足していたんですが、Composeでなにかしたくなったときに、定期的にこの仕組みを思い出したくなるので、書いておきます。
もう少しシンプルにして以下のようにします。
@Composable
private fun AndroidViewApp() {
LinearLayout {
TextView(
text = "This is the Android TextView!!",
)
}
}
LinearLayout()
やTextView()
は独自に定義したComposable関数です。
それを元の関数に展開したり、ちょっと関連が薄い部分を外すと以下になります。
以下のようにその要素を作る factory = {}
と、要素をアップデートできるupdate = {}
があります。
@Composable
private fun AndroidViewApp(context: Context) {
ComposeNode<LinearLayout, ViewApplier>(
factory = {
LinearLayout(context)
},
update = {},
content = {
val text = "This is the Android TextView!!"
ComposeNode<TextView, ViewApplier>(
factory = {
TextView(context)
},
update = {
set(text) {
this.text = text
}
},
)
}
)
}
ここに書いてあることで、それぞれのViewの作り方とアップデートの仕方はわかりました。
しかしどのように親Viewと子Viewを結びつけるのでしょうか?
それは以下のViewApplierにて実装しています。
このViewApplierが使われることによって親子関係が設定されることで利用できます。
class ViewApplier(val view: FrameLayout) : AbstractApplier<View>(view) {
override fun onClear() {
(view as? ViewGroup)?.removeAllViews()
}
override fun insertBottomUp(index: Int, instance: View) {
(current as? ViewGroup)?.addView(instance, index)
}
override fun insertTopDown(index: Int, instance: View) {
}
override fun move(from: Int, to: Int, count: Int) {
// NOT Supported
}
override fun remove(index: Int, count: Int) {
(view as? ViewGroup)?.removeViews(index, count)
}
}
このViewApplierは最初にComposition
というインスタンスを作るときに必要になり、これで親子関係が作られるようです。
Recomposerはいろいろ処理するところのようで、スタックトレースを見るとここからApplierやComposeNodeが呼ばれるようです。
val composer = Recomposer(Dispatchers.Main)
// composerの初期化処理
val rootView = FrameLayout(context)
Composition(ViewApplier(rootView), composer).setContent {
AndroidViewApp(context)
}
まとめ
ComposeはUIの部分と木構造を扱う部分からできている。
Applierが木構造を操作する。
ComposeNodeがそれぞれのノードの作成とアップデートを行う。
Author And Source
この問題について(Jetpack Composeの仕組みを使ってAndroid FrameworkのViewを作ってみて仕組みを知る), 我々は、より多くの情報をここで見つけました https://qiita.com/takahirom/items/2f749654e46c7cabdb57著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .