Kotlin/Composableって?
また知らない物がでてきた
ごくたまにAndroidアプリを作ったり、既存のアプリに機能を追加したりする、気ままなやり方で生きてきたのですが、久しぶりに開発環境(今はAndroid Studio)を開くとSDKを新しくしろとか、モジュールをアップデートしろとか言われてちょっとうんざりします。放置していた自分が悪いので、こちらから何も言い返せないのがまたストレスですよね。Gradleのことよくわかってないのに、たま挨拶する度に何回も構成が変わるし、何かビルド通らなくなってるし、私の知らないkところでいろいろ起こりすぎですよ。そんなアプデ地獄の中でもAndroid Studio本体のアップデートが年一くらいでやはりのしかかってくるじゃないですか。これはUIレベルで変更も入ったりしていて、前ここにあった物がなくなってる(廃止か移動か)とどこにいったか探すところから始めなくちゃいけなくて、おかげさまで私は永遠のスタジオ一年生の気持ちでいられます。新しいことを始めるつもりでやる、そのくらいの元気がないとアプリが作れません。
今回はAndroid Studioがクラゲになってました。Jellyfish・・・2023.3.1版のコードネームのようです。前はキリンだっけ、ハチの巣だっけ?短い付き合いでしたね。とりあえず、いろいろアプデ作業を終えて、今回はちょっとした自分用のアプリをチャチャッと作ろうかなって思っているので、新しいプロジェクトを作って、とりあえずレイアウトを決めるxmlを書き始めようかな、とメインアクティビティ用のレイアウトファイルを探したんですが、リソースフォルダの中になぜか、それが存在しませんでした。ん?一回、ビルドしてみたところ「Hello Android!」的ないつもの画面は出力されます・・・?ん?ん?画面はどこで誰が用意してるの?
まず、AndroidManifest.xmlをあたって、MAINという名のActivityを発見します。続いてMainActivity.ktを開いてみます。
@Composable fun Greeting(name: String, modifier: Modifier = Modifier) { ... }
ん?見慣れぬ@Composableというアノテーションがついた「Hello, World!」って言い出しそうな関数がファイルの中にみつかりました。MainActivityの外側にあるし、メソッドではなく純然たる関数ってことでいいんですかね。
Jetpack Compose現る
MainActivityにはMainActivityでonCreateメソッドの中にsetContentって書かれたパーツがあります。その中にテーマやらサーフェスやらが入れ子になっていて、さらにその中に先ほどのGreeting関数呼び出し部分が出てきました。Greetingの中にはまたTextとあって、どうもこのTextのtextプロパティっぽいものに「Hello $name!」って書いてあります。
HogeTheme └ Surface └ Greeting └ Text
↑まとめるとこんな親子関係が記述されてます。Textって多分テキストを表現するUIのことですよね。Androidアプリ的な呼び方はなんだっけ?コンポーネント?ビュー?とにかくここで出てきた構造が、これまでxmlに書いていたレイアウトの代わりを果たしていそうです。そういわれるとSurfaceはSurfaceViewに近いのかな?GreetingはカスタムUIみたいなものかもしれません。そして、Android StudioのMainActivity.ktの開いている部分の右肩をみると「Code」「Split」「Design」のも慣れた三兄弟もいらっしゃいました。なるほど、レイアウトファイルがソースファイルにくっついたんじゃないでしょうか?
この新しい仕組み何だろうと思って調べてみると「Jetpack Compose」というここ数年で使われ出した新しめなUI開発ツールなようです。(今2024年)迅速に簡便にパワフルな開発経験が積めるとか書いてありますが、でもどうせ複雑なことをしようとしたら、それなりに難解なことをさせられるんだろって身構えています。ただ、私は旧来の画面レイアウトの仕組みがすごく嫌いだったので、この新しい仕組みは大歓迎だったわけです。前のはごく簡単な見た目を書くのにも冗長的でやることが多すぎだったと思ってます。もっとしっかり取り組んだら便利だったのかもしれませんが、その気力が湧きあがらない面倒くささを感じてしまっていました。しかし、このJetpack Composeってやつは第一印象がよかったんですよね。ktファイルの中に書けるので、リソースXML画面と行き来しなくていいし、記述も簡素で、それでもそれなりの見た目が担保されてそうに見えます。まだ、その本領は不明ですが、使ってみたいという第一歩は踏み出せたようです。
@Composableアノテーション
で、@Composableってアノテーションはコンポーズ可能な関数を表すマークだそうです。私の解釈でいくと、このマークの付いたGreetingっていう関数はカスタムUIそのものと等価なイメージです。Textみたいな基本的な部品を集めて、新しい部品としてまた別のUI部品の中で再利用が可能になるのでしょう。Greetingを複数並べたりもきっとできるはずです。Greetingは一つのTextから構成されているわけですが、Textと異なるのは
- 関数に渡した任意の文字列に「Hello !」をつけて挨拶をするテキストだけ表示する
という点ですね。汎用性はTextに劣りますが、挨拶に特化したUIとして存在価値が高まるわけです。すくなくともこのGreetingを使っていれば、挨拶もできない非常識な奴にはならなくて済みそうです。
@Composableのついた関数の中で別の@Composableのついた関数が使えることになります。これはすなわち関数が表すUI部品は入れ子にできることを示しています。そして、後で検証が必要ですが、自分自身を入れ子にできるのかには注意していこうと思います。例えばGreetingを書き換えて「Aさんに挨拶したらAさんから返事の挨拶が返ってくる」ように実装したとします。
HogeTheme └ Surface └ Greeting(Aさんへの挨拶) └ Text └ Greeting(Aさんからの挨拶)
↑こんな感じでGreetingが入れ子にできたら、素人予想では「Aさんから返ってきた挨拶にさらに挨拶を返す」展開が起こりそうです。そして返事の返事に対しても返事が返り・・・
HogeTheme └ Surface └ Greeting(Aさんへの挨拶) └ Text └ Greeting(Aさんからの挨拶) └ Text └ Greeting(Aさんからの挨拶への挨拶) └ Text └ Greeting(Aさんからの挨拶への挨拶への挨拶) ...
無限ループ!再帰関数のことをつい心配してしまうのがプログラマですよね。挨拶なんてそこそこで切り上げなよ、って普通の人には呆れらるのです。無限に挨拶をしてしまう無限に愛想のいいアプリちゃんにどうやってわからせるのか楽しみです。
そしてonCreateの中のsetContentの役割はこれまでのAndroidアプリのやり方と新しいやり方をつなぐことにあるようです。Jetpack Composeのコンポーザルナ部品はsetContentの中になら書いていいってことらしいです。うん、何かできる気がしてきました。setContentの中に部品を詰めていけばよさそうですね。