Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mental Modles of Jetpack Compose

C6c3d6539516edbde775453d8a6867fb?s=47 Louis Tsai
September 25, 2019

Mental Modles of Jetpack Compose

With the raise of declarative UI, Jetpack Compose just might be the future of creating UI for Android. While the API is far from stable, there are already a lot of things that we can learn from other UI framework over the years, like React, Vue, and more recently, Flutter and SwiftUI.

Join me to learn some fundamental concepts (mental models) of this new way of building UI, and hopefully, when the time comes, you will be able to write idiomatic declarative UI with Jetpack Compose!

C6c3d6539516edbde775453d8a6867fb?s=128

Louis Tsai

September 25, 2019
Tweet

Transcript

  1. Mental Models of Jetpack Compose @louis993546

  2. Google I/O 2019 @louis993546

  3. import androidx.compose.* import androidx.ui.core.* @Composable fun Greeting(name: String) { Text

    ("Hello $name!") } @louis993546
  4. 1. Mental Model 2. Programming Paradigm 3. Inheritance 4. Composition

    5. Reactive Declarative UI 6. Component 7. Functional component 8. Hindsight @louis993546
  5. 1. Mental Model @louis993546

  6. A mental model is an explanation of someone's thought process

    about how something works in the real world. -- Wikipedia @louis993546
  7. 2. Programming Paradigm @louis993546

  8. State Visibility Data Flags @louis993546

  9. @louis993546

  10. val linearLayout = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } linearLayout.addView(

    TextView(context).apply { text = "Hello, World" } ) linearLayout.addView( ImageView(context).apply { imageResource = R.drawable.star } ) @louis993546
  11. val linearLayout = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL } //

    a statement (instruction) linearLayout.addView( TextView(context).apply { text = "Hello, World" } ) // another statement (instruction) linearLayout.addView( ImageView(context).apply { imageResource = R.drawable.star } ) // yet another statement (instruction) @louis993546
  12. Imperative programming val linearLayout = LinearLayout(context).apply { orientation = LinearLayout.VERTICAL

    } // a statement (instruction) linearLayout.addView( TextView(context).apply { text = "Hello, World" } ) // another statement (instruction) linearLayout.addView( ImageView(context).apply { imageResource = R.drawable.star } ) // yet another statement (instruction) @louis993546
  13. <LinearLayout orientation="vertical"> <TextView android:text="Hello, World"/> <ImageView android:src="@drawable/star"/> </LinearLayout> @louis993546

  14. <!-- beginning of definition --> <LinearLayout orientation="vertical"> <TextView android:text="Hello, World"/>

    <ImageView android:src="@drawable/star"/> </LinearLayout> <!-- end of definition --> @louis993546
  15. Declarative programming <!-- beginning of definition --> <LinearLayout orientation="vertical"> <TextView

    android:text="Hello, World"/> <ImageView android:src="@drawable/star"/> </LinearLayout> <!-- end of definition --> @louis993546
  16. Declarative programming <ConstraintLayout> <ImageView android:id="image_view" android:src="@drawable/star" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@+id/text_view"/> <TextView android:id="text_view"

    android:text="Hello, World" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/image_view"/> </ConstraintLayout> @louis993546
  17. 3. Inheritance @louis993546

  18. @louis993546

  19. Animal @louis993546

  20. Animal @louis993546

  21. @louis993546

  22. Commonalities Breath Walk Work Take over the world Blep Blop

    ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ @louis993546
  23. Commonalities Breath Walk Work Take over the world Blep Blop

    ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ Animal @louis993546
  24. Commonalities Breath Walk Work Take over the world Blep Blop

    Blup ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ @louis993546
  25. @louis993546

  26. @louis993546

  27. @louis993546

  28. 4. Composition @louis993546

  29. Commonalities Breath Walk Work Take over the world Blep Blop

    Blup ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ @louis993546
  30. Commonalities Breath Walk Work Take over the world Blep Blop

    Blup ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ @louis993546
  31. class : Breathable, Walkable, Workable, Blopable class : Breathable, Walkable,

    TakeOverTheWorldable, Blepable class : Walkable, Workable, TakeOverTheWorldable, Blupable @louis993546
  32. class : Breathable, Walkable, Workable, Blopable class : Breathable, Walkable,

    TakeOverTheWorldable, Blepable class : Walkable, Workable, TakeOverTheWorldable, Blupable class : Breathable, Blupable @louis993546
  33. 5. Reactive Declarative UI @louis993546

  34. @louis993546 S A B C D F ? XML ?

    ? ? ?
  35. @louis993546 S A B C D F ? XML ?

    ? ? ?
  36. Google I/O 2015 @louis993546

  37. <layout> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout android:orientation="vertical"> <TextView android:text="@{user.firstName}"/>

    <View android:visibility="@{user.age > 18 ? View.GONE : View.VISIBLE}" /> </LinearLayout> </layout> @louis993546
  38. S A B C D F ? XML Data Binding

    ? ? ? @louis993546
  39. JSConf US 2013 @louis993546

  40. Composition Declarative Programming + @louis993546

  41. React.js Move markup into logic Data Binding Move logic into

    markup @louis993546
  42. // a JavaScript file class HelloWorld extends React.Component { render()

    { // ↓ HTML ↓ JS ↓ Back to HTML return <h1>Hello, {this.props.target}!</h1> } } @louis993546
  43. UI = f(state) @louis993546

  44. sealed class ViewState { data class Success(val data: List<User>) :

    ViewState() data class Error(val error: Throwable) : ViewState() } viewStateLiveData.observe(this) { viewState -> when (viewState) { is Success -> { ... } is Error -> { ... } } } @louis993546
  45. WWDC 2019 @louis993546

  46. 6. Component @louis993546

  47. class HelloWorld extends React.Component { render() { return ( <h1>Hello,

    {this.props.target}!</h1> ) } } class HelloWorld extends React.Component { constructor(props) { super(props); this.state = {target: "World"} } componentDidMount() { console.log('mounting......') } componentWillUnmount() { /* ... */ } render() { return ( <h1>Hello, {this.state.target}!</h1> ) } } @louis993546
  48. @louis993546

  49. 1. Notify someone when click 2. Have a background 3.

    Display Text 1. Notify someone when click 2. Have a background 3. Display Image @louis993546
  50. 1. Notify someone when click 2. Have a background 3.

    Display Text 1. Notify someone when click 2. Have a background 3. Display Image @louis993546
  51. 1. Notify someone when click 2. Have a background 3.

    Display something @louis993546
  52. 1. Notify someone when click 2. Have a background 3.

    Display anything @louis993546
  53. //... FloatingActionButton( onPressed: () { // Add your onPressed code

    here! }, child: Icon(Icons.navigation), backgroundColor: Colors.green, ), //... @louis993546
  54. //... FloatingActionButton( onPressed: () { // Add your onPressed code

    here! }, child: Text('¯\_(ツ)_/¯'), backgroundColor: Colors.green, ), //... @louis993546
  55. class HelloWorld extends React.Component { render() { if (this.props.isFormal) {

    return /* 2000 lines of very complex layout #1 */ } return /* 2000 lines very complex layout #2 */ } } @louis993546
  56. class FormalHelloWorld extends React.Component { render() { return /* 2000

    lines of very complex layout #1 */ } } class InformalHelloWorld extends React.Component { render() { return /* 2000 lines of very complex layout #2 */ } } @louis993546
  57. Why now? • Better IDE (Autocomplete, linter, etc.) • Better

    performance -> Better developer ergonomics • Better languages (type inference, lambda/closure, etc.) ◦ JavaScript ◦ TypeScript/Flow ◦ Dart ◦ Swift ◦ Kotlin ◦ (Java 10+) • etc. @louis993546
  58. @louis993546 S A B C D F Flutter XML Data

    Binding React Compose SwiftUI
  59. 7. Functional component @louis993546

  60. class HelloWorld extends React.Component { constructor(props) { super(props); this.state =

    {target: "World"} } componentDidMount() { console.log('mounting......') } componentWillUnmount() { /* ... */ } render() { return ( <h1>Hello, {this.state.target}!</h1> ) } } @louis993546
  61. UI = f(state) @louis993546

  62. class HelloWorld extends React.Component { constructor(props) { super(props); this.state =

    {target: "World"} } componentDidMount() { console.log('mounting......') } componentWillUnmount() { /* ... */ } render() { return ( <h1>Hello, {this.state.target}!</h1> ) } } @louis993546
  63. function HelloWorld(props) { const [target, setTarget] = useState("World") useEffect(() =>

    log()) return <h1>Hello, {target}!</h1> } function log() { console.log('mounting......') } @louis993546 class HelloWorld extends React.Component { constructor(props) { super(props); this.state = {target: "World"} } componentDidMount() { console.log('mounting......') } componentWillUnmount() { /* ... */ } render() { return ( <h1>Hello, {this.state.target}!</h1> ) } } →
  64. function HelloWorld(props) { const [target, setTarget] = useState("World") useEffect(() =>

    log()) return <h1>Hello, {target}!</h1> } function log() { console.log('mounting......') } function HelloWorld2(props) { // ... log() // ... } @louis993546 class HelloWorld extends React.Component { constructor(props) { super(props); this.state = {target: "World"} } componentDidMount() { console.log('mounting......') } componentWillUnmount() { /* ... */ } render() { return ( <h1>Hello, {this.state.target}!</h1> ) } } →
  65. ReactConf 2018 @louis993546

  66. 8. Hindsight @louis993546

  67. perception of the nature of an event after it has

    happened -- Merriam-Webster @louis993546
  68. “Read later” • ${React.js stuff} ◦ React hooks • ${Flutter

    stuff} ◦ Material Components widgets • Architecture-stuff ◦ “Events & Data” ◦ MVI, BLoC, etc. ◦ Redux, MobX, etc. • Kotlin extension properties • Kotlin IR • Kotlin compiler plugin • How suspend function compiles • Virtual DOM @louis993546
  69. “Read later” • ${React.js stuff} ◦ React hooks • ${Flutter

    stuff} ◦ Material Components widgets • Architecture-stuff ◦ “Events & Data” ◦ MVI, BLoC, etc. ◦ Redux, MobX, etc. • Kotlin extension properties • Kotlin IR • Kotlin compiler plugin • How suspend function compiles • Virtual DOM @louis993546 https://bit.ly/2kVVO93
  70. @louis993546