Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Jetpack Compose 完全に理解した
Search
mkeeda
December 20, 2022
Programming
1
3.3k
Jetpack Compose 完全に理解した
2019/11/26にサイボウズ社内で開催した勉強会の資料です。
Jetpack ComposeがまだStableになるずっと前の情報をまとめたものになります。
mkeeda
December 20, 2022
Tweet
Share
More Decks by mkeeda
See All by mkeeda
What's new in Firebase for building gen AI features気になったところ
mkeeda
0
420
手動DIの教訓
mkeeda
0
150
WebViewと向き合う
mkeeda
2
1.1k
お気に入りのAndroid Studio小技集
mkeeda
0
290
Scalable UI testing solutions かんたんまとめ
mkeeda
0
920
5分で分かるビルドロジック共通化の今
mkeeda
1
1.1k
Compose で手に入れた UI の Unit test
mkeeda
3
1.6k
5分でわかるCompose Modifiers deep dive
mkeeda
1
910
みんなで準備するスポンサー
mkeeda
0
230
Other Decks in Programming
See All in Programming
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
1.9k
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
170
AWS IaCの注目アップデート 2024年10月版
konokenj
3
3.3k
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
初めてDefinitelyTypedにPRを出した話
syumai
0
400
イベント駆動で成長して委員会
happymana
1
320
アジャイルを支えるテストアーキテクチャ設計/Test Architecting for Agile
goyoki
9
3.3k
【Kaigi on Rails 2024】YOUTRUST スポンサーLT
krpk1900
1
330
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
Arm移行タイムアタック
qnighy
0
320
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Why Our Code Smells
bkeepers
PRO
334
57k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Transcript
Jetpack Compose 完全に理解した ϞόΠϧνʔϜ ҪాҰฏ
Jetpack Compose ってなに? 2 🤔
Kotlin でめっちゃええ感じに UI を作るやつ https://developer.android.com/jetpack/compose 3
めっちゃええ感じ? Less Code Intuitive 💡 Accelerate Development 🚄 Powerful ⚡
~.xml は不要になり、Kotlin だけで UI を作成可能 UI を宣⾔するだけ。状態が変化すると UI は⾃動更新 既存のコードと完全に互換。Android Studio がライブプレビュー Material Design, ダークテーマ, アニメーションなどをサポート 4
すごそう👏 5
Jetpack Compose で 何が変わる? 6 🤔
“Jetpack Compose” 7 🤔
Jetpack = Unbundle なツールキット🚀 • Android は OS アップデートの普及が遅い 😨
• Android 9.0 のシェア: 10.4 % • iOS 13 のシェア: 50 % • OS バージョンに依存する API は中々使われない 🤢 • 新しい API を OS アップデートに含めて配布しても使われない 🤮 • Support library → Jetpack 8
“Jetpack Compose” 9 🤔 🚀
Compose = UI を “構成する” 何か 10 weblio より
今までの “UI を構成する” 11 1. データが与えられたとき、何を表⽰するか 2. イベントに対して何をするか 3. UI
は時間経過でどのように変化すべきか 4. レイアウトの定義 (my_fragment.xml, attrs.xml, styles.xml )
3. UI は時間経過でどのように変化すべきか 12 99+ 10 10 99+ 10 99+
99+
命令型プログラミングで時系列を記述する⾟さ 13 99+ 10 fun updateCount(count: Int) { if (count
== 0) { removeBadge() } else if (count <= 99 && hasBadge()) { setBadgeText(count) } else if ... }
Jetpack Compose の “UI を構成する” 14 1. データが与えられたとき、何を表⽰するか 2. イベントに対して何をするか
3. UI は時間経過でどのように変化すべきか 4. レイアウトの定義 (my_fragment.xml, attrs.xml, styles.xml )
Jetpack Compose 基礎編 15
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) setContent { Greeting("Ippei") } } } @Composable fun Greeting(name: String) { Text("Hello $name") } UI を表⽰する 16
UI は関数の組み合わせで構成する • @Composable をつける • Composable 関数は データを UI
に変換する • データは引数として受け取る • Composable 関数は Composable 関数を呼び出せる 17 @Composable fun Greeting(name: String) { Text("Hello $name") }
@Composable fun Greeting(name: String) { if (name == "Ippei") {
Text("Hello $name") } else { Text(text = "You are not Ippei") } } @Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } } 18
19
@Composable fun NewsStory(newsItem: NewsItem) { val image = +imageResource(newsItem.imageId) Card(elevation
= 2.dp, shape = RoundedCornerShape(4.dp)) { Column(crossAxisSize = LayoutSize.Expand) { Container(expanded = true, height = 180.dp) { DrawImage(image = image) } Column(modifier = Spacing(16.dp)) { Text(text = newsItem.title, maxLines = 2, overflow = TextOverflow.Ellipsis, style = (+themeTextStyle { h6 }).withOpacity(0.87f)) Text(text = newsItem.author, style = (+themeTextStyle { body2 }).withOpacity(0.87f)) } } } } 20
UI を更新するときは Composable に新しいデータを渡す 21 Data UI Data UI Composable
UI を更新する
• ViewModel, LiveData, Rx, Coroutines + Flow • View が
ViewModel のデータを継続して購読する 22 Data View (UI) Reactive programming ViewModel Data
• @Model を付けたクラスは、観測可能 & スレッドセーフになる • Composable 関数は、Model のプロパティを⾃動で購読 23
@Model Composable UI UI Data Data Model
@Model data class LikeButtonState( var count: Int = 0 )
@Composable fun LikeButton( state: LikeButtonState = LikeButtonState() ) { Button( text = "${state.count} Like", onClick = { state.count++ } ) } @Model で状態管理 24
Single source of truth * 25
View の持つ状態は誰が管理している? 26 誰が View のイベントに反応する? 誰が状態を所有してる? 誰が状態を更新する?
android.widget.CheckBox 27 // CheckBox CompoundButton ͷαϒΫϥε (Java) public abstract
class CompoundButton extends Button implements Checkable { private static final String LOG_TAG = CompoundButton.class.getSimpleName(); private boolean mChecked; … // Activity or Fragment (Kotlin) checkBox.setOnCheckedChangeListener { checkBox, isChecked -> // After changed ... checkBox.isChecked = true }
android.widget 😩 28 誰が View のイベントに反応する? 誰が状態を所有してる? 誰が状態を更新する? View ではない
Listener を実装した誰か 1つの View の状態を複数箇所で所有可能 基本的に View ⾃⾝が更新するが、誰でも更新可能
Single source of truth 29 誰が View のイベントに反応する? 誰が状態を所有してる? 誰が状態を更新する?
状態の所有者がイベントに反応する。 状態の所有者は常に1つ。 状態の所有者のみが更新する。
Single source of truth in Compose 30 @Model class FormState(var
optionChecked: Boolean = false) @Composable fun Form(formState: FormState = FormState()) { Checkbox( checked = formState.optionChecked, onCheckedChange = { newState -> formState.optionChecked = newState } ) } ※ CheckBox の⽂⾔は別途 Text で表⽰する必要がある
Data flows 🔄 31
データの流れは⼀⽅向 32 NewsContent NewsCard NewsCard NewsCard Image Text Image Text
Image Text Business Logics User Data Events ▪ = Composable
@Composable fun NewsContent(newsItems: List<NewsItem>) { newsItems.forEach { newsItem -> NewsCard(newsItem)
} } @Composable fun NewsCard(newsItem: NewsItem) { Column { SimpleImage( image = +imageResource(newsItem.imageId) ) Text(text = newsItem.title) } } データはトップダウンに伝搬 • 引数で渡す • 親 → ⼦ へ伝搬 • グローバル変数を参照しない 33
イベントはボトムアップに伝搬 ラムダ式を引数として 親 → ⼦ に渡す 34 NewsContent NewsCard NewsCard
Image Text Image Text Business Logics User Events ▪ = Composable { } { } { }
35 @Composable fun NewsContent( newsItems: List<NewsItem>, newsState: NewsState = NewsState()
// Model ) { Column { TopAppBar(title = { Text(text = newsState.selectedNewsTitle ?: "not selected") }) newsItems.forEach { newsItem -> NewsCard( newsItem = newsItem, onClick = { newsState.selectedNewsTitle = newsItem.title } ) } } } @Composable fun NewsCard(newsItem: NewsItem, onClick: () -> Unit) { Clickable(onClick = onClick) { // Image ͱ Text } } ※ スタイルは調整してあります
既存コードとの互換性 (未実装) 36
Composable → View 変換 (予定) 37 What's New in Jetpack
Compose (Android Dev Summit ’19) のスライドより
Composable 内で View を使う 38 • ⾃作したコンポーネントや外部ライブラリとの共存させたい • ViewBinding ?
• 既存の View をラップした Composable を⽤意する? • 既存の View は Single source of truth の設計ではない問題
🚀 Jetpack Compose ⚒ 39 1. Unbundle な UI ツールキットの提供
2. 宣⾔的な記述による UI 時系列の気配りからの解放 3. 簡潔な状態管理とイベントハンドリングの実現 4. Kotlin の⾔語機能をフルに使ったレイアウト ※ Technical Preview なのでプロダクトにはまだ使えない
Jetpack Compose の正体 🔍 40 UIツールライブラリ Composable 関数, Material Theme,
etc Kotlin コンパイラプラグイン @Composable, @Model からのコード⽣成 +
その他 • Layout • Effects & memo • Theme •
気になる⼈は Codelab を⾒てね! https://codelabs.developers.google.com/codelabs/jetpack-compose-basics/#0 41