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.7k
Jetpack Compose 完全に理解した
2019/11/26にサイボウズ社内で開催した勉強会の資料です。
Jetpack ComposeがまだStableになるずっと前の情報をまとめたものになります。
mkeeda
December 20, 2022
Tweet
Share
More Decks by mkeeda
See All by mkeeda
DataStoreをテストする
mkeeda
0
330
時計仕掛けのCompose
mkeeda
1
370
What's new in Firebase for building gen AI features気になったところ
mkeeda
0
630
手動DIの教訓
mkeeda
0
200
WebViewと向き合う
mkeeda
2
1.3k
お気に入りのAndroid Studio小技集
mkeeda
0
340
Scalable UI testing solutions かんたんまとめ
mkeeda
0
1.1k
5分で分かるビルドロジック共通化の今
mkeeda
1
1.5k
Compose で手に入れた UI の Unit test
mkeeda
3
1.9k
Other Decks in Programming
See All in Programming
マテリアルって何者?RealityKitで扱うマテリアル入門
nao_randd
0
130
TVer iOSチームの共通認識の作り方 - Findy Job LT iOSアプリ開発の裏側 開発組織が向き合う課題とこれから
techtver
PRO
0
610
バリデーションライブラリ徹底比較
nayuta999999
1
210
OpenTelemetryで始めるベンダーフリーなobservability / Vendor-free observability starting with OpenTelemetry
seike460
PRO
0
160
ユーザーにサブドメインの ECサイトを提供したい (あるいは) 2026年函館で一番熱くなるかもしれない言語の話
uvb_76
0
160
What Spring Developers Should Know About Jakarta EE
ivargrimstad
1
390
rbs-traceを使ってWEARで型生成を試してみた After RubyKaigi 2025〜ZOZO、ファインディ、ピクシブ〜 / tried rbs-trace on WEAR
oyamakei
0
460
Proxmoxをまとめて管理できるコンソール作ってみました
karugamo
1
380
ソフトウェア品質特性、意識してますか?AIの真の力を引き出す活用事例 / ai-and-software-quality
minodriven
19
6.3k
Design Pressure
hynek
0
1.4k
〜可視化からアクセス制御まで〜 BigQuery×Looker Studioで コスト管理とデータソース認証制御する方法
cuebic9bic
0
210
Cloudflare Workersで進めるリモートMCP活用
syumai
13
1.9k
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
49
7.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
It's Worth the Effort
3n
184
28k
Building Adaptive Systems
keathley
41
2.6k
Six Lessons from altMBA
skipperchong
28
3.8k
How to train your dragon (web standard)
notwaldorf
92
6k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
The Invisible Side of Design
smashingmag
299
50k
VelocityConf: Rendering Performance Case Studies
addyosmani
329
24k
Producing Creativity
orderedlist
PRO
345
40k
Balancing Empowerment & Direction
lara
0
70
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