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

Workshop on Jetpack compose

Adit Lal
January 03, 2023

Workshop on Jetpack compose

MAD with Jetpack compose workshop slides

Adit Lal

January 03, 2023
Tweet

More Decks by Adit Lal

Other Decks in Programming

Transcript

  1. Android development with Jetpack Compose

  2. Android GDE 
 🛠 Individual Consultant 
 🔊 Speaker 


    🌎 Globe Tro tt er 
 🍻 Beer enthusiast 🎯https:/ /androiddev.social/@aditlal 🔗aditlal.dev
  3. This work is licensed under the Apache 2.0 License

  4. None
  5. Jetpack Compose / jet ·pak kuhm· powz / noun Jetpack

    Compose is a declarative & modern toolkit for building native Android UI. It simpli fi es and accelerates UI development on Android.
  6. Why do we need Compose? What does it solve and

    how?
  7. Before Compose UI Toolkit is tied to the OS State

    Management is tricky Lots of context switching Simple things still require a lot of code
  8. With Compose UI Toolkit is independent to the OS 🪄

    State Management is built in🥳 Lots of context switching 🎉 So rt ed code logic 🚀
  9. None
  10. Activity class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { . . . } } }
  11. Activity class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { . . . } } }
  12. setContent public fun ComponentActivity.setContent( parent: CompositionContext? = null, content: @Composable

    () - > Unit ) { / / some magic code🪄 } }
  13. What are we gonna learn today?

  14. TOPIC TIME(in hr:mins) Thinking in Compose 0:05 Modifiers 0:20 Layouts

    0:30 State management 0:45 SideEffects 1:00 Codelab - idea Today’s Schedule
  15. Imperative

  16. <ConstraintLayout> <ImageView /> <TextView /> <TextView /> </ ConstraintLayout> Imperative

  17. View Group View Imperative

  18. val textView = findViewById(R.id.textView) Imperative

  19. textView.text = ... Imperative val textView = findViewById(R.id.textView)

  20. Declarative UI

  21. ✓ Declarative UI is cleaner, more readable, and more performant

    than Imperative UI. ✓ Compose allows you to do more with less code compared to XML. ✓ Compose is Intuitive. This means that you just need to tell Compose what you want to show the user. ✓ Compose is compatible with all your existing code: you can call Compose code from Views and Views from Compose. Also integrated with many Jetpack Libraries. ✓ Compose improves your build time and APK size. Declarative UI Compose
  22. Hello Adit Declarative UI

  23. @Composable fun Greeting(name: String) { } Declarative UI

  24. @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }

    Hello Adit Declarative UI
  25. Update state? Hello Mike Declarative UI

  26. Modifiers

  27. Text ( modifier = Modifier .padding(10.dp), text = "Hello World"

    ) Hello World Modifiers
  28. Text ( modifier = Modifier . background (Color.Green), text =

    "Hello World" ) Hello World .padding(10.dp) Modifiers
  29. Text ( modifier = Modifier . border( width = 2.dp,

    color = Color.Green ), text = "Hello World" ) Hello World .padding(10.dp) Modifiers
  30. Text ( modifier = Modifier text = "Hello World" )

    Hello World Order ma tt ers . border( width = 2.dp, color = Color.Green ) .padding(10.dp) .padding(10.dp), Modifiers
  31. Hello World Text ( modifier = Modifier . border( width

    = 2.dp, color = Color.Green ), text = "Hello World" ) .padding(10.dp) Order ma tt ers Modifiers
  32. Hello World Text ( modifier = Modifier .border( width =

    2.dp, color = Color.Green ) .background(Color.Green), text = "Hello World" ) .padding(10.dp) Modifiers
  33. h tt ps://developer.android.com/jetpack/compose/modi fi ers-list

  34. Layouts

  35. Column

  36. Column { } Column

  37. Column { Text ( "Hello Text ( "Hello Text (

    "Hello } World" ) World" ) World" ) Hello World Hello World Hello World Column Column { }
  38. Column( verticalArrangement = ) } { X Y Column Arrangement.Center

  39. Hello World Hello World Hello World Column Column( verticalArrangement =

    ) } { Arrangement.SpaceBetween
  40. Column( horizontalAlignment = ) } { X Y Column

  41. Hello World Hello World Hello World Column Column( horizontalAlignment =

    ) } { Alignment.End
  42. Column Column( horizontalAlignment = ) } { Alignment.CenterHorizontally Hello World

    Hello World Hello World
  43. Row

  44. Row { Text ( “Hello" ) Text ( "World" )

    Text ( “!" ) HelloWorld! } Row
  45. Row( horizontalArrangement = ) } { X Y Row

  46. Hello World ! Row Row( horizontalArrangement = ) } {

    Arrangement.SpaceBetween
  47. Row( verticalAlignment = ) } { X Y Row

  48. HelloWorld! Row Row( verticalAlignment = ) } { Alignment.CenterVertically

  49. Column Row Ve rt ical Arrangement Horizontal Arrangement Horizontal Alignment

    Ve rt ical Alignment Row & Column
  50. Row & Column

  51. Row { Image(…) } Row & Column

  52. Row { Image(…) Column { } } Row & Column

  53. Row { Image(…) Column { Text ( “…” ) Text

    ( “…” ) } } Row & Column
  54. Box

  55. Box { Image(…) } Box

  56. Box { Image(…) Column { Text(…) Text(…) } } Box

  57. Box } Box { Image(…) Column(Modifier.align(Alignment.BottomEnd)) { Text(…) Text(…) }

  58. List

  59. fun EmployeeListView (items: List<Item>) { LazyColumn { } } List

    @Composable
  60. @Composable fun EmployeeListView (items: List<Item>) { LazyColumn { items (items)

    { item -> } } } List
  61. @Composable fun EmployeeListView (items: List<Item>) { LazyColumn { items (items)

    { item -> ItemRow(item) } } } List
  62. Slot Layouts

  63. Scaffold(topBar = {}) { } Slot Layouts

  64. Home Slot Layouts Text(text = “Home") Scaffold(topBar = { {

    } })
  65. Hello World Slot Layouts Text(text = “Home") Scaffold(topBar = {

    { } }) Home Text(text = “Hello World”)
  66. • Column • Row • Box • Sca ff old

    Layouts
  67. Layout modifiers

  68. Layout modifiers

  69. Column { Hello World Hello World } Text( text =

    "Hello World”, modifier = Modifier.background(Color.Green) ) Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Layout modifiers
  70. Column ( Modifier .background(Color.Green) .fillMaxWidth() ) { } Hello World

    Hello World Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Layout modifiers
  71. Hello World Hello World Column ( Modifier .background(Color.Green) .fillMaxSize() )

    { } Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Layout modifiers
  72. Hello World Hello World 200dp Column ( Modifier .background(Color.Green) .width(200.dp)

    ) { } Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Text( text = "Hello World”, modifier = Modifier.background(Color.Green) ) Layout modifiers
  73. State management

  74. • Setup state using mutableStateOf State management

  75. 0 + - State management

  76. val counter by remember { mutableStateOf(0) 0 } State management

  77. Column { Text ( text = counter.toString() 0 ) ...

    } State management
  78. Button ( ) { onClick = { counter ++ }

    0 Text ( text = "+" ) } + - State management
  79. Button ( ) { onClick = { counter -- }

    0 Text ( text = “-" ) } + - State management
  80. Composable UI-Redraw Event Recomposition

  81. Val counter by remember { mutableStateOf(0) 0 } + -

    Recomposition
  82. Search State management

  83. View Model Event Search Search View State management

  84. SideEffects

  85. • Work outside of composable function • Open new screen

    when tapping bu tt on • Show no network message SideEffects
  86. A side effect of composition that must be reversed or

    cleaned up if the DisposableEffect leaves the composition. It is an error to call DisposableEffect without at least one key parameter. Schedule effect to run when the current composition completes successfully and applies changes. SideEffect can be used to apply side effects to objects managed by the composition that are not backed by snapshots so as not to leave those objects in an inconsistent state if the current composition operation fails. When LaunchedEffect enters the composition it will launch the block into the composition's CoroutineContext. The coroutine will be canceled and re-launched when LaunchedEffect is recomposed with a different key1. The coroutine will be canceled when the LaunchedEffect leaves the composition. LaunchedEffect SideEffect DisposableEffect SideEffects
  87. A side effect of composition that must be reversed or

    cleaned up if the DisposableEffect leaves the composition. It is an error to call DisposableEffect without at least one key parameter. Schedule effect to run when the current composition completes successfully and applies changes. SideEffect can be used to apply side effects to objects managed by the composition that are not backed by snapshots so as not to leave those objects in an inconsistent state if the current composition operation fails. When LaunchedEffect enters the composition it will launch the block into the composition's CoroutineContext. The coroutine will be canceled and re-launched when LaunchedEffect is recomposed with a different key1. The coroutine will be canceled when the LaunchedEffect leaves the composition. LaunchedEffect SideEffect DisposableEffect SideEffects
  88. • Triggers on fi rst composition or key change @Composable

    fun HomeView () { var counter by remember { mutableStateOf ( 0 ) } } LaunchedEffect
  89. • Triggers on fi rst composition or key change @Composable

    fun HomeView () { var counter by remember { mutableStateOf ( 0 ) } } LaunchedEffect { while(true) { counter ++ } } LaunchedEffect
  90. • Triggers on fi rst composition or key change @Composable

    fun HomeView () { var counter by remember { mutableStateOf ( 0 ) } } LaunchedEffect { while(true) { counter ++ } } delay(2000) LaunchedEffect
  91. • Triggers on fi rst composition or key change @Composable

    fun HomeView () { var counter by remember { mutableStateOf ( 0 ) } } LaunchedEffect(key1 = Unit){ while(true) { counter ++ } } delay(2000) LaunchedEffect
  92. Schedule effect to run when the current composition completes successfully

    and applies changes. SideEffect can be used to apply side effects to objects managed by the composition that are not backed by snapshots so as not to leave those objects in an inconsistent state if the current composition operation fails. When LaunchedEffect enters the composition it will launch the block into the composition's CoroutineContext. The coroutine will be canceled and re-launched when LaunchedEffect is recomposed with a different key1. The coroutine will be canceled when the LaunchedEffect leaves the composition. LaunchedEffect SideEffect SideEffects A side effect of composition that must be reversed or cleaned up if the DisposableEffect leaves the composition. It is an error to call DisposableEffect without at least one key parameter. DisposableEffect
  93. • Calls SideE ff ect when we want conditional e

    ff ect @Composable fun SearchBar() { } val focusRequester = remember { FocusRequester() } SideEffect { if(focused && !isSearchDummy) focusRequester.requestFocus() } SideEffect
  94. A side effect of composition that must be reversed or

    cleaned up if the DisposableEffect leaves the composition. It is an error to call DisposableEffect without at least one key parameter. Schedule effect to run when the current composition completes successfully and applies changes. SideEffect can be used to apply side effects to objects managed by the composition that are not backed by snapshots so as not to leave those objects in an inconsistent state if the current composition operation fails. When LaunchedEffect enters the composition it will launch the block into the composition's CoroutineContext. The coroutine will be canceled and re-launched when LaunchedEffect is recomposed with a different key1. The coroutine will be canceled when the LaunchedEffect leaves the composition. LaunchedEffect SideEffect DisposableEffect SideEffects
  95. DisposableEffect • Calls onDispose on terminate @Composable fun HomeView() {

    DisposableEffect (...) { onDispose { callback.remove() } } }
  96. 101

  97. Code class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { NotesApplicationTheme { / / A surface container using the 'background' color from the theme Surface( modif i er = Modif i er.f i llMaxSize(), color = MaterialTheme.colors.background ) { Greeting("Android") } } } }
  98. Code class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { NotesApplicationTheme { / / A surface container using the 'background' color from the theme Surface( modif i er = Modif i er.f i llMaxSize(), color = MaterialTheme.colors.background ) { Greeting("Android") } } } }
  99. Code class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { NotesApplicationTheme { / / A surface container using the 'background' color from the theme Surface( modif i er = Modif i er.f i llMaxSize(), color = MaterialTheme.colors.background ) { Greeting("Android") } } } }
  100. Code class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { NotesApplicationTheme { / / A surface container using the 'background' color from the theme Surface( modif i er = Modif i er.f i llMaxSize(), color = MaterialTheme.colors.background ) { Greeting("Android") } } } }
  101. Code class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) setContent { NotesApplicationTheme { / / A surface container using the 'background' color from the theme Surface( modif i er = Modif i er.f i llMaxSize(), color = MaterialTheme.colors.background ) { Greeting("Android") } } } }
  102. Composable @Composable fun Greeting(name: String) { Text(text = "Hello $name!")

    } @Preview(showBackground = true) @Composable fun DefaultPreview() { NotesApplicationTheme { Greeting("Android") } }
  103. Demo https://developer.android.com/codelabs/jetpack-compose-basics

  104. https://github.com/aldefy/Andromeda 
 https://bit.ly/3Nic0JF - Sample catalog app 
 
 Andromeda

    is an open-source Jetpack Compose design system. A collection of guidelines and components can be used to create amazing compose app user experiences. Foundations introduce Andromeda tokens and principles while Components provide the bolts and nuts that make Andromeda Compose wrapped apps tick. Check out
  105. Thats all folks! https://linktr.ee/aldefy