†混沌とした令和のAndroid界隈を照らす一筋の光†
レイアウトをKotlinで書くのって何それおいしいの?(旨味がなさそうの意)
「なんでこんなん使うんや」という疑問から軽く情報をさらってみた(具体的な実装にはほとんど触れません)
当方、知識不足という致命的なバグを抱えているので、解釈が間違っていたら優しく教えてくださいませ
命令的UIから宣言的UIへ
これが1番大きな違いである!(わかってない)
そもそも命令的だとか宣言的だとか、おおよそ日本で暮らしていて出会ったことのない単語なんだよな
あぁ~Reactとかのアレね、アレ!(わかってない)という粒度から始めていく
命令的UI
- 何をするか という 命令的 な処理でもって表示されたUI
- 表示させるUI自体ではなく、UIを表示する 過程を記述 する
val binding = HogeFragmentBinding.bind(view)
if(binding.hogeText.text == "Hello World!")
binding.fugaText.text = "hogehoge"
↑ fragment_hoge.xmlをよしなにBindingしてな
↑ その中にあるhoge_textというIdのtextが"Hello World"なら、fuga_textに"hogehoge"をセットするんや!
ということが 命令的 に書かれている
別にええやん? 何が問題あるん?
これがJetpack Composeだ、と紹介されても何も不便を感じなさそう
・・・とここで大問題が起こった
神の声「さらにfugaTextを用意しろ、それにhogehogeTextとfugafugaTextとhogehogehogeTextとfugafugafugaTextと・・・を用意してhogeTextが"Hello World"なら全部"hogehoge"に変えるんや!」
莫大な量の追加仕様に立ち向かう新人エンジニアの駆け出しくん、1行1行テキストを追加していく
binding.hogehogeText.text = "hogehoge"
binding.hogehogehogeText.text = "hogehoge"
binding.hogehogehogehogeText.text = "hogehoge"
binding.fugaText.text = "hogehoge"
binding.fugafugaText.text = "hogehoge"
binding.fugafugafugaText.text = "hogehoge"
binding.fugafugafugafugaText.text = "hogehoge"
.
.
.
「ふぇぇ。。。何がなんだかわからないよぉ。。。」
xmlファイルとkotlinのファイルを行ったり来たりしながら、幼女になった駆け出しくんは困って泣いてしまった。
そして呟く
「"何が表示されている"のか一目でわかるシステムが欲しいよぉ。。。」
宣言的UI
- 何が表示されている のかということを 宣言 するUI
- 表示する過程に興味はなく、 表示された結果 を記述する
val hoge = "Hello World"
Column() {
Text(text = hoge)
if(hoge == "Hello World"){
Text(text = "hogehoge")
Text(text = "hogehoge")
Text(text = "hogehoge")
・
・
・
}
}
↑Textという文字列を表示させる関数があるで
↑それをhogeの状態に合わせて構成( compose )していくで
ということが 宣言的 に書かれている
こ、これが"宣言型プログラミング パラダイム"!!!!
命令的UIと比べると ここに何があるのか ということが 直感的 にわかる感じがする!
それにKotlinとXMLの間を行ったり来たりする必要がない!
それならもうJetpack Composeを使うしかないよね
で、Jetpack Composeってなんだろう
Jetpack Composeが宣言型で使いやすいことは分かったけれど、結局まだ何も触れていないんだよな
ほな、Composeの思想でも読んでいくか。。。
ワイ「コンポーズばっかり言わないで!」 知能ちゃん「うるさいですね。。。」
コンポーズがゲシュタルト崩壊していく
文章が苦手なワイのために無愛想な知能ちゃんが3行でまとめてくれた
- @Composableアノテーションがついた関数はUIを出力する関数として扱われる(よって返り値を必要としない)
- コンポーズ可能な関数がコンポーズ可能な関数を呼び出してUI階層を構築する
- コンポーズ可能な関数はべき等で、同じ引数で何度呼び出しても同じ出力となる(関数のみで完結している)
知能ちゃんありがとう! ということは
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
上の関数GreetingはTextという Composableな関数 を呼び出している
TextはTextViewの役割を果たして、textの値をUIとして出力する
Greeting("World")
なんて宣言すると、
こんな感じにHello World!ができるってことだね
ColumnやRowのような レイアウトを構成する要素 や、Buttonのような 画面に出力される要素 、それにModifierなんていう 修飾子 を呼び出しながらレイアウトに組み込んでいくのか!
関数が呼び出された先を辿っていけばいずれ最初の関数に当たるから、 データの流れ がよく分かって読みやすいコードになるね
やるやん、Jetpack Compose
もしかして影響受けるのってView層だけ!?
僕がJetpack Composeくんの調査をする前に危惧していたことは、ドメイン層やデータ層まで全てひっくり返ってAndroidアーキテクチャが終焉を迎え、AACがゴミになって世界が壊滅するということだった(あまりにも無知)
実際はそんなこともなく、うまく宣言的なコードが書けるようになっている訳でした、めでたしめでたし
Jetpack Composeの記事なのにほとんど宣言的UIと命令的UIの調査になってしまったな
また今度ちゃんとシバこうと思います