Jetpack Compose Beta Overviewの動画を見たのでまとめる
注意
- 本記事はYouTubeのAndroid Developersチャンネルにおいて投稿された動画である Jetpack Compose: Beta overviewについて、動画内で述べられていることと、一部筆者の主観が入っている記事となっております。
- 記事内で使用される画像は、Jetpack Compose: Beta overviewより引用させていただいております。(不都合等ありましたらコメントをお願いします)
- 動画を全範囲網羅している記事ではありません。
Jetpack Composeとは?
1. Modern, declarative UI tool kit
- Composeは、宣言的UIを可能にするUIツールキット。
- 宣言的UIとは?
- どのように見えるか(What)を記述し、どのように作るか(How)を記述しない
2. Built on Kotlin
- Kotlinで作られており、Composeの関数のような、直感的なAPIを構築するのに十分な表現力
3. Unbundled
- Composeは他のJetpackライブラリと同様にアンバンドルされています。
- プロジェクトのペースで更新できるように、APIバージョン間で一貫した動作をする
- アンバンドルとは?
- Androidのプラットフォームに含まれておらず(unbundle)、ライブラリとして追加できる
4. Built for interop
- 相互運用(interop)を重視している
- 例えば、新規の画面から徐々にComposeに移行することができるみたいな
現在のJetpack Composeの状況
- Jetpack Composeは現在Betaである(2021/04/15時点)
- APIの洗練と安定化に焦点を当てて開発中
Jetpack Composeの推しポイント
- ComposeはAndroidのUIをよりはやく・簡単に実装することができる
- なぜ、はやく・簡単に実装することができるのか?
- 宣言的とUIツールの2つに分解して説明していく
まず宣言的について
従来のアプローチ(慣例的なアプローチ)
上の図の例は、入門書などに書かれている一般的な例。
XMLがあり、その状態を変更するために、findViewById()
などをして、プロパティを設定する。
例えば、DBやネットワークから情報をActivity・Fragmentが受け取ったとき、その情報をもちいてUIを更新するなど。
この問題点はStateがXMLとFragment/Activityの両方に存在すること。
例えば、上図のTextViewのテキストをAPIの結果に応じて変化させる場合を考える。
XMLのレイアウトファイルにTextViewがあり、初期のテキストが設定されているとする
そして、APIの結果として、文字列を受け取ったときにその情報を格納する変数をFragment・Activityに定義していたとする。
TextViewの状態、Fragment・Activityの状態の2つが存在する。
Fragment・Activity間の状態を、TextViewの状態に反映するには、setText()
などを使用しなければいけない。
この手続き的な操作は、開発者の責任で行う必要があり、バグの原因となってしまう。
JetPack Composeのアプローチ
上図のようにStateとUIがあり、Stateは変化するもので、UIは普遍で変更されないもの。
状態が変化した際に、UI全体が再生成される(効率化のために実際には差分のみの再生成となる)
先ほどの例(TextViewのテキストをAPIの結果に応じて変化させる場合)について考えてみる。
状態はFragment・Activityで保持する1つのみとなり、状態としてTextViewに表示する文字列が入っている。
APIリクエストがあり、状態の変更を検知して、状態をもとにUIを再生成する。
何が良いのか?
これにより、状態に応じて自動的にUIが変更されることになる。
例えば、先ほどの例でいうところの、setText()
という手続きが不要になる。
結果として、手続きの記述漏れなどによるバグがなくなる。
コードレベルで確認していく!
- 上記コードの説明
- 文字列のリストを表示する単純なコンポーネント
- 関数は何も返さないが、UIをemitする
-
message
の中身が空の場合は「No messsages」を、それ以外の場合はメッサージをテキストとして表示 - 関数が実行されたら、新しいUIが作成される
- これをRecomposingと呼ぶ。メッセージの状態が変わったら、UIが再生成される
messageの変化をどう検知するのか?
- 上記のコードの説明
- ViewModelにおいて、
message
をLiveDataで公開
- ViewModelにおいて、
// おそらくこんな感じ
class ConversationViewModel: ViewModel() {
private val _message = MutableLiveData("")
val message: LiveData<String> = _message
:
- LiveDataで新しいデータを検知するたびに
MessageList(message)
が呼ばれUIが再生成される - 注意点
- Composableはimmutableなので、参照を保持して、後で照会したり、内容を更新することはできない
- したがって、全ての情報をEmit時にパラメーターとして渡す必要がある
しかしながら、コンポーネントが変化できないということを意味するわけではない
すべてのメッセージを選択するチェックボックスを追加して、すべてのメッセージを選択できるようにしてみる。
上記のコードだと、チェックボックスをクリックしても視覚的には切り替わらない。(cheched = false
)としているので。
なので、状態を更新して、チェックボックスをemitする必要がある
どうするか?
チェックするかどうかのローカルな状態を持たせる。
そして、CheckBox()
のパラメータonCheckChange
にユーザがチェックしたときのコールバックを設定する。
このようにすることで、チェックボックスの状態であるselectAll
がクリック時に更新され、チェックボックスへ視覚的な状態が反映される。
しかしこれだと、UIにロジックがあって気持ち悪い
下記のように、MessageList()
のパラメータとして、ステートと更新のためのラムダを渡す。
Composeはどういうアーキテクチャが適しているか?
基本的には、Composeはどのようなアプリケーション・アーキテクチャにも対応できる。
特に一方向性のデータ・フローとの相性が良く、ViewModelが画面の状態のストリームを公開しているとき。
各コンポーネントはパラメーターとして状態を受け取り、データが更新された場合にのみUIを更新する。
1つのLiveDataを使用することで、状態を一元化でき、画面全体の状態についての理解が簡単になりエラーを減らせる。
宣言的についてのまとめ
Composeを使用すると Single Source Of Truth(信頼できる唯一の情報源) の原則が守れる。
慣習的なアプローチでは、Fragment・Activityで保持している状態とViewが保持している状態の2つがあり、バグの原因となる可能性があった。
しかし、Composeを使用すると状態を一元管理することができる。
そして「状態に変化があったときに、自動でUIが変更される」という性質により、バグが生まれにくくなる。
UIツールについて
ComposeはUIコンポーネントの豊富なツールキットを提供している。
機能やメリット
Material Design ComponentとMaterial Themingのサポート
Material Design Component | Material Theming |
---|---|
シンプルだがパワフルなレイアウトシステムを提供
例えば、Row
というComposableは、LinearLayoutのorientation
をhorizontal
に指定したレイアウトとほぼ同等。
しかし、Viewシステムが異なり、ネストされたレイアウトをパフォーマンスの高いものにしてくれるメリットがある。
より複雑なレイアウトを表現するために、ConstraintLayoutも提供されている。
アニメーションシステム
UIに動きをつけることが、より使いやすく、非常にパワフルになっている。
MotionLayoutをComposeに導入する作業も行っている
テスト
Composeは、テストを容易にするために専用のテストシステムを提供する。
そして、Composablesを個別にテストするための簡単なAPIを提供する。
アニメーションのテストも書くことができる。
Kotlinで書かれている
Kotlinの優れた言語機能のおかげで、シンプルで直感的なAPIとなっている。
例えばCoroutineを使用することによって、シンプルな非同期APIを作成できるようにしている。
Coroutineを使用して、タッチ検出がブロックされないように、新しいコルーチンで押された位置にアニメーションさせている。
具体例で確認していく!
下記レポジトリの中のJetchat
というアプリで説明。
https://github.com/android/compose-samples
レイアウトの説明
上記のレイアウトを作るには下記のことを行っている
- message(=表示するテキスト)、isFromMe(=自分からのメッセージがどうかのフラグ)をパラメータに持つComposableを作成
- メッセージ全体を囲むCard Composableを作成
- isFromMeに応じて、Themeから色を指定
- 実際にテキストを表示するためにText Composableを作成
- Modifierパラメータ用いてpaddingを設定
開発・検証方法
@Preview
アノテーションを用いてプレビュー用のComposableを作成する。
それをAndroid Studio上で確認することが可能
この後、細かい実装方法が紹介されているので割愛。
述べられている内容
- ComposableのパラメータにModifierを渡して、再利用可能に
- Modifierでは、最大幅やテキストのAlignmentなどを指定
-
LazyColumn
を使用してRecyclerViewのような効率的なスクロールの実装 - など
推しポイントまとめ
宣言的なUIによって、Composeを使用するとSingle Source Of Truth(信頼できる唯一の情報源)の原則が守れる。
UIツールによって、レイアウトやアニメーションの実装が簡単になる。
-> 簡単に、はやく実装することができる
まだまだ推しポイントはある
既存のViewシステムと共存できる
Interoperability APIと呼ばれるものが用意されている
:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
:
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
:
</LinearLayout>
class ExampleFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(
R.layout.fragment_example, container, false
).apply {
findViewById<ComposeView>(R.id.compose_view).setContent {
// In Compose world
MaterialTheme {
Text("Hello Compose!")
}
}
}
}
}
コードの引用: https://developer.android.google.cn/jetpack/compose/interop?hl=ja#interop-apis
他の主要なライブラリとの統合を提供
資料等
Composeの学習系
フィードバック等
Author And Source
この問題について(Jetpack Compose Beta Overviewの動画を見たのでまとめる), 我々は、より多くの情報をここで見つけました https://qiita.com/YusukeSuzuki1213/items/e593fa01ff737b8e835f著者帰属:元の著者の情報は、元の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 .