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.5k
Jetpack Compose 完全に理解した
2019/11/26にサイボウズ社内で開催した勉強会の資料です。
Jetpack ComposeがまだStableになるずっと前の情報をまとめたものになります。
mkeeda
December 20, 2022
Tweet
Share
More Decks by mkeeda
See All by mkeeda
時計仕掛けのCompose
mkeeda
1
290
What's new in Firebase for building gen AI features気になったところ
mkeeda
0
510
手動DIの教訓
mkeeda
0
180
WebViewと向き合う
mkeeda
2
1.2k
お気に入りのAndroid Studio小技集
mkeeda
0
320
Scalable UI testing solutions かんたんまとめ
mkeeda
0
1k
5分で分かるビルドロジック共通化の今
mkeeda
1
1.4k
Compose で手に入れた UI の Unit test
mkeeda
3
1.8k
5分でわかるCompose Modifiers deep dive
mkeeda
1
990
Other Decks in Programming
See All in Programming
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
150
TokyoR116_BeginnersSession1_環境構築
kotatyamtema
0
110
第3回 Snowflake 中部ユーザ会- dbt × Snowflake ハンズオン
hoto17296
4
370
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
520
[Fin-JAWS 第38回 ~re:Invent 2024 金融re:Cap~]FaultInjectionServiceアップデート@pre:Invent2024
shintaro_fukatsu
0
410
Rails アプリ地図考 Flush Cut
makicamel
1
120
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
890
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
340
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
550
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
10
3.5k
SRE、開発、QAが協業して挑んだリリースプロセス改革@SRE Kaigi 2025
nealle
3
4.3k
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.2k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
Navigating Team Friction
lara
183
15k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
330
BBQ
matthewcrist
87
9.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
Building Your Own Lightsaber
phodgson
104
6.2k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Faster Mobile Websites
deanohume
306
31k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Building Applications with DynamoDB
mza
93
6.2k
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