本セッションの登壇者
セッション動画
皆さんこんにちは、あんざいゆきです。Google Developer Experts for Androidをしています。私からはJetpack Compose 1.2の新機能について紹介していきます。
ネイティブUI開発者必携! Jetpackの今
Jetpack Composeとは、ネイティブUIをビルドするためのAndroidの最新ツールキットです。去年あたりからstableが出ていて、徐々に使われてきているのかなという感じです。特徴としては、UIを宣言的に記述できるというものです。

現在のstableのバージョンは1.2.1になっています。今年の6月からCompose Compilerは独立したバージョンをとるようになり、Composeが最新のKotlinバージョンで使えるようになるまでの期間が短くなりました。以前はKotlinの新しいバージョンが出てもComposeが対応するまでけっこう待たされていましたが、すぐ使えるようになってきています。

では、ここからCompose 1.2.0および1.2.1の新機能を紹介します。
進化し続ける新機能
開発者モードを有効にしたアプリ開発用デバイスでは、Developer optionsでさまざまな設定が可能になっています。
その中にアニメーションの速度を変える設定があります。アニメーションを毎回走らせていると時間がかかるので、短くしたいといったことが可能になります。この設定値がJetpack Composeのアニメーションにも反映されるようになりました。

次に、RTL(Right to Left)レイアウトのときに、vector imageを自動でミラーリングするように設定できるようになりました。

VectorPainterを取得するためにrememberVectorPainter()というメソッドを使うのですが、このメソッドにImageVectorを指定するときは、ImageVectorのauto mirror設定が使われるようになっています。
iconsオブジェクトにmaterial iconsのImageVectorが定義されていますが、auto mirror設定がfalseになっているので、これらを使った場合はRTLレイアウトでも反転しません。

一方で、rememberVectorPainter() にサイズとパスを指定して、自分でその場でベクターイメージを作るVectorPainterを取得することができます。この場合はautoMirrorを自分で設定できるので、RTLのときに反転させることができます。

さらに、AnimatedImageVectorからアニメーションを表示をさせるVectorPainterを取得する場合は、rememberAnimatedVectorPainter()を使います。こちらでは外からは指定しないのですが、内部でauto mirrorがtrueになっているので、このアニメーションするImageVectorは、RTLレイアウトで反転するようになっています。

次に、新しいeasingがたくさん追加されています。以前は4つだけでしたが、ここに書いたようにかなりたくさん追加されています。新しいeasingは全部、EasingFunctions.ktというファイルに定義されていて、それぞれコメントにGIFへのリンクがあるので、そこから右上のようなグラフを見られます。

続いてLazyListのuserScrollEnabledというパラメーターが追加されたというお話です。こちらはuserScrollEnabledにfalseを指定すると、指でスクロールしてもスクロールしなくなるというものです。ユーザーのスクロールは防いで、プログラムでスクロールさせたいときに使います。

また、SelectionContainer内で選択ハンドルをドラッグしているときに拡大表示が出るようになりました。以前はハンドルは出ても拡大表示は出ていませんでした。

続いて、Modifier.systemGestureExclusion() が追加されています。このModifierを指定することで、その領域をシステムジェスチャーから除く領域として指定できます。この例では、Modifier.systemGestureExclusion()で青い領域全体と赤い領域の上半分を指定しているので、その領域ではシステムのバックジェスチャーがきかなくなっています。

LazyColumn、LazyRow、LazyVerticalGridなどのLazyList系のitemに、content typeを指定できるようになりました。LazyColumnのデフォルトでは、スクロールアウトしても再利用のためにContent typeごとに最大7個のコンポーネントがコンポーネントツリーに残ります。
content typeを指定しないとitemのcontent typeがnullになります。nullもcontent typeの一種として扱われます。

ダウンローダブルフォントが使えるようになりました。Googleフォントをよく使うと思いますが、Googleフォントを使う場合は、ui-text-google-fontsライブラリが別途必要になります。

LazyColumnやLazyRowのベース機能が、LazyLayout composableとしてまとめられました。このLazyLayoutを直接使うことで、右の絵のような独自の配置のLazyListを作ることができます。ただし、スクロールなども自前でやらなければならないのでけっこう大変です。

TextStyle、SpanStyleでBrushが使えるようになりました。これにより文字色をグラデーションにできるようになっています。

Chip系のcomposableが追加されました。押すだけのボタン系Chipと、選択可能な状態を持つFilterChipが用意されています。

独自の見た目の入力フォームを作るときに、BasicTextFieldのDecorationBoxで入力エリアに色をつけたり、ヒントを出したりする機能を自分で実装します。TextFieldやOutlinedTextField composableは見た目やヒントの機能があらかじめ実装されていて便利なのですが、見た目のカスタマイズがあまりできませんでした。
そこで、TextField composableとOutlinedTextField composableの見た目部分、DecorationBoxでやっている部分の処理が、TextFieldDecorationBox、OutlinedTextFieldDecorationBoxとして提供されるようになっています。これによって、ヒントを出す機能などはこちらを利用しつつ、見た目はTextFieldよりも凝ったものにしたいといったことができるようになりました。

movavleContentOf()という機能が追加されています。これはcomposable lambdaをrememberすることで、compose treeの中で場所が変わっても再コンポジションされない仕組みです。次のバージョンの1.3.0で追加されるLookaheadLayoutと組み合わせるとShared transitionが可能になるので、そのための仕組みが先に入っています。

単数複数で違いのある言語用に文字列を定義するpluralResourceというものがあります。composeにはこのpluralResourceの文字列を取得する関数が今までなかったのですが、追加されています。

WindowInsetsというのは、ステータスバーやナビゲーションバーなどのサイズを扱うための機能です。今まではAccompanistのinsetsライブラリを使うのがデファクトでしたが、同等の機能が本体に取り込まれています。

パディングとして取ったり、幅や高さとして取ったり、値を追加したり、組み合わせたりできるようになっています。


キーボード周りとフォーカス処理を改良
バグの修正についても少し紹介します。Composeは入力フォームを扱う際にバグがあるとよく言われていましたが、たとえばCJKキーボードでバックスペースを長押ししても一文字しか消えなかったのが、連続して消えるようになりました。また、キーボードタイプが異なるテキストフィールド間をフォーカスが移動したときに一瞬キーボードがちらつくなどがあったのですが、それも直っています。

また、フォーカスの処理も改善されています。LazyColumnではフォーカス移動で下の方に行ってもスクロールしなかったのが、1.2からはフォーカス移動でスクロールするようになりました。

既存レイアウトとの相性も◎
まとめです。
Jetpack Compose 1.2では、LazyLisyのcontent typeなどの新しい機能が入ったり、入力フォーム周りのバグ修正があったりなど、いろいろと改善されています。
まだJetpack Composeアプリを入れていない方にはぜひ導入していただけたらと思います。既存のレイアウトと一緒に使えて、段階的に少しずつ入れてみることもできます。

以上です。ありがとうございました。