Save 37% off PRO during our Black Friday Sale! »

Jetpack Compose さわってみた / tried writing code with Jetpack Compose

D1a0c0bb255c9e352972f7879aed3672?s=47 kenken
August 15, 2019

Jetpack Compose さわってみた / tried writing code with Jetpack Compose

D1a0c0bb255c9e352972f7879aed3672?s=128

kenken

August 15, 2019
Tweet

Transcript

  1. Jetpack Compose さわってみた @tkhs0604 #love_kotlin Kotlin愛好会 vol.14 @ Wantedly, Inc.

  2. 人生初登壇です

  3. • 高橋 健太 ◦ kenken | @tkhs0604 ◦ https://tkhs0604.hatenablog.com •

    Gunosy Inc. • SI営業→エンジニア(iOS/Android/Web)→Androidエンジニア • アカペラ ◦ 最近ORICON NEWSに少しだけ載りました 自己紹介
  4. • 開催日:2019/8/24(土) • 場 所:東京コンファレンスセンター品川 5F • (LT枠ですが) 登壇します Kotlin Fest

    2019
  5. • 自分のことを覚えて帰っていただく← • Jetpack Composeの使い方を完全に理解していただく 本日のゴール

  6. • Jetpack Compose とは ◦ 宣言的UIとは • UI生成までの流れ • コンポーネントの作成方法

    ◦ @Composable ◦ @Model • まとめ • さらに知りたい方へ アジェンダ
  7. Jetpack Compose とは

  8. • Google I/O 2019 • Android Jetpack • Kotlin •

    宣言的UI ◦ cf. Flutter、React Native、Litho、Vue.js • Pre-alpha版 (2019/8/12時点) ◦ ⚠大きく変更が入る可能性があります Jetpack Compose とは
  9. • Concise and Idiomatic Kotlin ◦ Kotlinにより簡潔に記述可能 • Declarative ◦

    フレームワークによる描画の最適化 • Compatible ◦ 既存のView (Android API)と併用可能 • Enable Beautiful Apps ◦ Material Designやアニメーションが利用可能 • Accelerate Development ◦ Apply Changes、Live Previewの活用 → 未だなさそう? コアコンセプト
  10. • Concise and Idiomatic Kotlin ◦ Kotlinにより簡潔に記述可能 • Declarative ◦

    フレームワークによる描画の最適化 • Compatible ◦ 既存のView (Android API)と併用可能 • Enable Beautiful Apps ◦ Material Designやアニメーションが利用可能 • Accelerate Development ◦ Apply Changes、Live Previewの活用 → 未だなさそう? Jetpack Compose の コアコンセプト 宣言的?
  11. 宣言的UIとは 宣言的 命令的 What (何をするか)を記述 How (どのようにするか)を記述 遅延評価 即時評価 //

    android.widget.Button Button(this).apply { text = "button" setBackgroundColor(Color.BLUE) setOnClickListener { ... } } // androidx.ui.material.Button Button( text = "button", color = +themeColor { Color.Blue }, onClick = { … } )
  12. UI生成までの流れ

  13. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } }
  14. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } } • Activityの拡張関数 • Root ViewとなるFrameLayoutの準備 • 引数で受け取ったコンポーネントを Root Viewの直下へ追加
  15. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } } • 各種リソースへアクセスするための設定 ◦ Context ◦ Density ◦ FocusManager ◦ TextInputService • 引数で受け取ったコンポーネントを AndroidCraneViewへ追加
  16. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } } • コンポーネントのThemeの設定 ◦ TextStyleやColorの設定も関数で行う
  17. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } } • コンポーネントのAlignの設定 ◦ MarginやPaddingの設定も関数で行う
  18. Hello World class SampleActivity : Activity() { override fun onCreate(savedInstanceState:

    Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { Text( text = "Hello World", style = +themeTextStyle { h3 } ) } } } } } • Android APIでいうところのTextView +…?
  19. コンポーネントの作成方法

  20. コンポーネントの作成 • @Composableを関数に付与することでコンポーネントとして認識 される • コンポーネントが満たさなければならない条件 ◦ 引数で与えられる値以外を操作しない ◦ 副作用が生じるようなパラメータは引数で受け取る

  21. コンポーネントの作成 @Composable fun CounterWidget() { Column { Text( text =

    "Count: 0", style = +themeTextStyle { h5 } ) Button( text = "+" ) } }
  22. コンポーネントの作成 class SampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { CraneWrapper { MaterialTheme { Center { CounterWidget() } } } } }
  23. • モデルクラスを作成する ◦ @Modelをクラスに付与する • モデルクラスを利用する ◦ コンポーネント内で+state関数によって状態管理用の Stateオブジェクトを生成する •

    Stateオブジェクトのプロパティが更新されると、 フレームワークによってUIが再描画される 状態を持ったコンポーネントの作成
  24. 状態を持ったコンポーネントの作成 @Model data class CounterModel( var count: Int ) @Composable

    fun CounterWidget() { Column { val counter by +state { CounterModel(0) } Text( text = "Count: ${counter.count}", style = +themeTextStyle { h5 } ) Button( text = "+", onClick = { counter.count++ } ) } }
  25. 状態を持ったコンポーネントの作成 @Model data class CounterModel( var count: Int ) @Composable

    fun CounterWidget() { Column { val counter by +state { CounterModel(0) } Text( text = "Count: ${counter.count}", style = +themeTextStyle { h5 } ) Button( text = "+", onClick = { counter.count++ } ) } } • プリミティブ型、String型の場合は val counter = +state { 0 } で呼び出し可能
  26. 状態を持ったコンポーネントの作成 @Model data class CounterModel( var count: Int ) @Composable

    fun CounterWidget() { Column { val counter by +state { CounterModel(0) } Text( text = "Count: ${counter.count}", style = +themeTextStyle { h5 } ) Button( text = "+", onClick = { counter.count++ } ) } } • @Modelの付与されたクラスでないと UIの再描画はされない
  27. まとめ

  28. • まだまだ資料は全然少ない • 開発環境も整っていない (AOSPを直接DLするしか現状ない) • 独特の記法(+state関数など)がところどころあるので、 逐一実装を追って理解するのがしんどい • 今までkt/javaファイル、layout.xml、attrs.xml、drawable.xmlに書

    いていたことを集約できるので、開発が進めば便利になりそうな気 はする • まだあわてるような時間じゃない 所感
  29. さらに知りたい方へ

  30. Kotlin Community • Kotlin Slackへの参加申請 (#composeチャンネル) ◦ https://surveys.jetbrains.com/s3/kotlin-slack-sign-up

  31. Thank you very much for listening.