Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
What to Upload to SlideShare
Loading in …3
×
1 of 21

Jetpack Compose - A Lightning Tour

1

Share

Download to read offline

Talk given at GDG Auckland in May 2019 on explorations into a new reactive UI framework announced by Google at I/O 2019.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Jetpack Compose - A Lightning Tour

  1. 1. Jetpack Compose A lightning tour GDG Auckland - May 2019
  2. 2. Disclaimer • I’m not an expert on any of this :) • This is the result of building the sample, exploring source code and some reading • Flutter and React devs - feel free to speak up • Compose is pre-alpha and not ready for production
  3. 3. What is it? • A “…modern, reactive style UI toolkit for Android, which takes advantage of Kotlin and integrates seamlessly with the platform and all of your existing code.” • Declarative - “Simply describe your UI as a set of composable functions, and the framework handles UI optimizations under the hood and automatic updates to the view hierarchy.” • Inspired by/similar to Flutter, React, Litho • Way to allow the Android UI Framework to evolve, unbundled from platform releases • Create smaller, reusable UI components by composing lower-level UI components, e.g.:
  4. 4. Composable UI components /** * The Bills card within the Rally Overview screen. */ @Composable fun RallyBillsCard() { Card(color = cardInternalColor) { Column { Padding(padding = 12.dp) { Column { Text(text = "Bills", style = +themeTextStyle { subtitle2 }) Text(text = "$1,810.00", style = +themeTextStyle { h1 }) } } } } }
  5. 5. Counter app class CounterActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { CounterApp() } } } @Composable fun CounterApp() { val counter = +state { 0 } MaterialTheme { Button(onClick = { counter.value++ }) { Text(text = "Counter = ${counter.value}") } } } }
  6. 6. Q: Wtf is going on here:
 val counter = +state { 0 } @Composable fun CounterApp() { val counter = +state { 0 } MaterialTheme { Button(onClick = { counter.value++ }) { Text(text = "Counter = ${counter.value}") } } }
  7. 7. Q: Wtf is going on here:
 val counter = +state { 0 } @Composable fun CounterApp() { val result: Effect<State<Int>> = state { 0 } val counter: State<Int> = +result MaterialTheme { Button(onClick = { counter.value++ }) { Text(text = "Counter = ${counter.value}") } } }
  8. 8. Q: Are components just implemented with Fragments/Views? • No*, widgets are just functions that ultimately make canvas draw calls.
  9. 9. @Composable fun ColoredRect(brush: Brush, width: Dp? = null, height: Dp? = null) { Container(width = width, height = height, expanded = true) { DrawFillRect(brush = brush) } } @Composable private fun DrawFillRect(brush: Brush) { Draw { canvas, parentSize -> val paint = Paint() brush.applyBrush(paint) canvas.drawRect(parentSize.toRect(), paint) } }
  10. 10. Tangent: KTX tags (?!) @Composable fun Draw( children: @Composable() () -> Unit = {}, @Children(composable = false) onPaint: DrawScope.(canvas: Canvas, parentSize: PxSize) -> Unit ) { // Hide the internals of DrawNode <DrawNode onPaint={ canvas, parentSize -> DrawScope(this).onPaint(canvas, parentSize) }> children() </DrawNode> }
  11. 11. Tangent: KTX tags (?!)
  12. 12. Tangent: KTX tags (?!) @Composable fun RallyApp() { val counter = +state { 0 } RallyTheme { Scaffold(appBar = { RallyAppBar() }) { Padding(padding = 16.dp) { Button(onClick = { counter.value++ }) { Text(text = "Counter = ${counter.value}", style = +themeTextStyle { h3 }) } } } } }
  13. 13. Tangent: KTX tags (?!) @Composable fun RallyApp() { val counter = +state { 0 } <RallyTheme> <Scaffold appBar={ <RallyAppBar /> }> <Padding padding=16.dp> <Button onClick={ counter.value++ }> <Text text="Counter = ${counter.value}" style=+themeTextStyle { h3 } /> </Button> </Padding> </Scaffold> </RallyTheme> }
  14. 14. Automatic XML -> KTX conversion <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello world!"/> </LinearLayout>
  15. 15. Automatic XML -> KTX conversion
  16. 16. Automatic XML -> KTX conversion (kinda…)
  17. 17. Q: Are components just implemented with Fragments/Views? • No*, widgets are just functions that ultimately make canvas draw calls. • *In practise, you need at least one special View: AndroidCraneView • Typically you won’t create this directly, but via CraneWrapper, e.g.: override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { CraneWrapper { RallyApp() } } }
  18. 18. Q: How do I check it out? • Short answer - follow this guide: https://medium.com/ q42-engineering/try-jetpack-compose-today- a12bda50aed2
  19. 19. Q: How do I check it out? Longer answer: • Get a Repo client (Google’s VCS) • Check out the androidx branch of AOSP (~3GB) • Run a script to DL/build a custom unstable version of Android Studio (30min+) • Play with the sample projects
  20. 20. Further Reading/Watching • Diving into Jetpack Compose - Thijs Suijten
 https://medium.com/q42-engineering/android-jetpack- compose-895b7fd04bf4 • Android Jetpack Compose Review - Karumi. Mentions some areas for improvement
 https://blog.karumi.com/android-jetpack-compose-review/ • Android developers page
 https://developer.android.com/jetpack/compose • Declarative UI Patterns (Google I/O’19)
 https://youtu.be/VsStyq4Lzxo
  21. 21. Thank you Questions, opinions, further thoughts? Matt Clarke
 Twitter: @kiwiandroiddev

×