Slide 1

Slide 1 text

Jetpack Compose どうなの? Yuki Anzai (@yanzm) at Android Dev Summit 2019 報告会

Slide 2

Slide 2 text

Yuki Anzai • Google Developer Expert for Android • Twitter : @yanzm

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Jetpack Compose ってなに? • Android の UI を作るための(モダンな)ツールキット • Kotlin • minSdkVersion = 21 • 既存のコード(View, XMLで構成されるUI)と混ぜて使える

Slide 5

Slide 5 text

Jetpack Compose がやりたいこと • もっとシンプルにしたい • 今までの⽅法だと、⼊⼒⽂字列でフィルタリングできるリストを作るの にたくさんコード書かないといけない • private な API に開発者が依存せざるを得ない状況をやめたい • Material + animations な UI にしたい

Slide 6

Slide 6 text

Jetpack Compose がやりたいこと • single source of truth がやりたい • CheckBox が持つ状態(isChecked)と Model が持つ状態 (isFavorite)どっちが正しいの?問題 • reactive UI がやりたい • single source of truth である Model が変わったら、⾃動で UI が変わ るようにしたい

Slide 7

Slide 7 text

Jetpack Compose がやりたいこと • UI パーツの再利⽤性を⾼めたい • ⼩さくて特定の役割にフォーカスした Composableを組み合わせて UI を作る

Slide 8

Slide 8 text

What's new for Jetpack Compose • セッション • 「What's New in Jetpack Compose 」 • https://www.youtube.com/watch?v=dtm2h-_sNDQ • 「Understanding Compose」 • https://www.youtube.com/watch?v=Q9MtlmmN4Q0

Slide 9

Slide 9 text

What's new for Jetpack Compose • Developer Preview : 0.1.0-dev02 • Android Studio 4.0 Canary 1 から簡単に試せるようになった • Not ready for production!!!!!(製品で使える段階じゃない、使うな、危 険) • 来年 beta が出るというアナウンス

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Jetpack Compose を試す • Android Studio 4.0 Canary 3 をインストールする • [Start a new Android Studio project] - [Empty Compose Activity]

Slide 12

Slide 12 text

プレビュー

Slide 13

Slide 13 text

Composable function • fun に @Composable をつける → Composable function @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }

Slide 14

Slide 14 text

Composable function • fun に @Composable をつける → Composable function • Composable function は Composable function からしか呼べない @Composable fun Greeting(name: String) { Text(text = "Hello $name!") } library で⽤意されている Composable function

Slide 15

Slide 15 text

Composable function • fun に @Composable をつける → Composable function • Composable function は Composable function からしか呼べない • UI Components = Composable functions のこと @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }

Slide 16

Slide 16 text

@Composable fun MyList() { VerticalScroller { Column(crossAxisSize = LayoutSize.Expand) { for (i in 0 until 20) { ListItem(text = "item : $i") } } } }

Slide 17

Slide 17 text

プレビュー • Composable function に @Preview をつける @Preview @Composable fun DefaultPreview() { Greeting("Android") }

Slide 18

Slide 18 text

プレビュー • Composable function に @Preview をつける • 引数なし @Preview @Composable fun DefaultPreview() { Greeting("Android") }

Slide 19

Slide 19 text

プレビュー • Composable function に @Preview をつける • 引数なし • コードを変更したら Build Refresh で更新 @Preview @Composable fun DefaultPreview() { Greeting("Android") }

Slide 20

Slide 20 text

@Model • single source of truth • プロパティとして値(状態)を持つ • class に @Model をつけると Observable な機能が追加される • Composable function は参照している @Model の可変プロパティを⾃動 で subscribeし、値が変わったら⾃動で recompose する(Composable function が再度呼ばれる) @Model class FavoriteState( var isFavorite: Boolean = false )

Slide 21

Slide 21 text

val names = listOf("Donuts", "Eclair", "Froyo") @Model class NameState(var value: String = "") @Composable fun RandomName() { val nameState = NameState() Column { Text(text = "Hello ${nameState.value}!") Button( onClick = { nameState.value = names.random() }, text = "next" ) } }

Slide 22

Slide 22 text

val names = listOf("Donuts", "Eclair", "Froyo") @Model class NameState(var value: String = "") @Composable fun RandomName() { val nameState = NameState() Column { Text(text = "Hello ${nameState.value}!") Button( onClick = { nameState.value = names.random() }, text = "next" ) } }

Slide 23

Slide 23 text

val names = listOf("Donuts", "Eclair", "Froyo") @Model class NameState(var value: String = "") @Composable fun RandomName() { val nameState = NameState() Column { Text(text = "Hello ${nameState.value}!") Button( onClick = { nameState.value = names.random() }, text = "next" ) } }

Slide 24

Slide 24 text

val names = listOf("Donuts", "Eclair", "Froyo") @Model class NameState(var value: String = "") @Composable fun RandomName() { val nameState = NameState() Column { Text(text = "Hello ${nameState.value}!") Button( onClick = { nameState.value = names.random() }, text = "next" ) } } recompose

Slide 25

Slide 25 text

val names = listOf("Donuts", "Eclair", "Froyo") @Composable fun RandomName() { val nameState = +state { "" } Column { Text(text = "Hello ${nameState.value}!") Button( onClick = { nameState.value = names.random() }, text = "next" ) } } @Model class State(value: T)

Slide 26

Slide 26 text

どんな UI Components がある? • androidx.ui:ui-layout:$version • レイアウト関係 • androidx.ui:ui-material:$version • Material Design 関係 • ConstraintLayout 今作ってる最中です Jetnews サンプルを⾒るとよい

Slide 27

Slide 27 text

MaterialTheme { Column { Text("Hello Android") Button("button") Button("button", style = OutlinedButtonStyle()) Checkbox(true, {}) RadioGroup(listOf("Donuts", "Eclair", "Froyo"), "Donuts", {}) Switch(true, {}) val vector = +vectorResource(R.drawable.ic_android_black_24dp) Container(width = 24.dp, height = 24.dp) { DrawVector(vector) } val image = +imageResource(R.drawable.yanzm) SimpleImage(image) } }

Slide 28

Slide 28 text

Custom View を作るには? • Draw と Layout を使う @Composable fun DrawBox() { val paint = Paint() paint.color = Color.Blue paint.style = PaintingStyle.fill Draw { canvas: Canvas, _: PxSize -> val size = 200.dp.value val offset = 20.dp.value val radius = Radius.circular(20.dp.value) val rect = RRect(offset, offset, size + offset, size + offset, radius) canvas.drawRRect(rect, paint) } }

Slide 29

Slide 29 text

Custom View を作るには? • Draw と Layout を使う @Composable fun Stack( children: @Composable() () -> Unit ) { Layout(children) { measurables, constraints -> val placeables = measurables.map { it.measure(constraints) } val maxWidth = placeables.map {it.width.value}.max()!!.ipx val maxHeight = placeables.map { it.height.value }.max()!!.ipx layout(maxWidth, maxHeight) { placeables.forEach { it.place(0.ipx, 0.ipx) } } } }

Slide 30

Slide 30 text

Custom View を作るには? • Draw と Layout を使う Stack { DrawBox() Text("Donuts", style = TextStyle(Color.LightGray, 30.sp)) }

Slide 31

Slide 31 text

既存の View と使うには • Compose UI を既存の UI で使う : @GenerateView (予定) • まだない • 既存の UI を Compose UI で使う • 特に情報なし

Slide 32

Slide 32 text

Jetpack Compose やるべき? • Layout XML はオワコンですか? • 既存の UI の作り⽅が廃⽌されるわけではない • Java → Kotlin のように⼀部分だけ導⼊できるようにしていく • 今から試しておくべき? • チームは API への意⾒を求めているのでフィードバックがあればぜひ

Slide 33

Slide 33 text

Resources

Slide 34

Slide 34 text

Portal site • https://developer.android.com/jetpack/compose

Slide 35

Slide 35 text

Codelab • https://codelabs.developers.google.com/codelabs/jetpack- compose-basics

Slide 36

Slide 36 text

Sample • https://github.com/ android/compose-samples/ tree/master/JetNews • Android Studio で [Import Sample...] - [Jetnews sample]

Slide 37

Slide 37 text

まとめ • Android Studio 4.0 Canary で Jetpack Compose を簡単に試せるように なった • 来年 beta が出る • まだまだ製品で使えるような段階ではない • まずは試してみよう!