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

    View Slide

  2. Android GDE

    🛠 Individual Consultant

    🔊 Speaker

    🌎 Globe Tro
    tt
    er

    🍻 Beer enthusiast
    🎯https:/
    /androiddev.social/@aditlal
    🔗aditlal.dev

    View Slide

  3. This work is licensed under the Apache 2.0 License

    View Slide

  4. View Slide

  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.

    View Slide

  6. Why do we need Compose?
    What does it solve and how?

    View Slide

  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

    View Slide

  8. With Compose
    UI Toolkit is independent to the OS 🪄


    State Management is built in🥳


    Lots of context switching 🎉


    So
    rt
    ed code logic 🚀

    View Slide

  9. View Slide

  10. Activity
    class MainActivity : ComponentActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {


    super.onCreate(savedInstanceState)


    setContent {


    . . .

    }


    }


    }

    View Slide

  11. Activity
    class MainActivity : ComponentActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {


    super.onCreate(savedInstanceState)


    setContent {


    . . .

    }


    }


    }

    View Slide

  12. setContent
    public fun ComponentActivity.setContent(


    parent: CompositionContext? = null,


    content: @Composable ()
    - >
    Unit


    ) {

    / /
    some magic code🪄


    }


    }

    View Slide

  13. What are we gonna learn
    today?

    View Slide

  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

    View Slide

  15. Imperative

    View Slide





  16. ConstraintLayout>
    Imperative

    View Slide

  17. View Group
    View
    Imperative

    View Slide

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

    View Slide

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

    View Slide

  20. Declarative UI

    View Slide

  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

    View Slide

  22. Hello Adit
    Declarative UI

    View Slide

  23. @Composable


    fun Greeting(name: String) {


    }
    Declarative UI

    View Slide

  24. @Composable


    fun Greeting(name: String) {


    Text(text = "Hello $name!")


    }
    Hello Adit
    Declarative UI

    View Slide

  25. Update state?
    Hello Mike
    Declarative UI

    View Slide

  26. Modifiers

    View Slide

  27. Text (


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

    View Slide

  28. Text (


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

    View Slide

  29. Text (
    modifier = Modifier
    . border(


    width = 2.dp,


    color = Color.Green


    ),
    text = "Hello World"
    )
    Hello World
    .padding(10.dp)
    Modifiers

    View Slide

  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

    View Slide

  31. Hello World
    Text (
    modifier = Modifier
    . border(


    width = 2.dp,


    color = Color.Green


    ),
    text = "Hello World"
    )
    .padding(10.dp)
    Order ma
    tt
    ers
    Modifiers

    View Slide

  32. Hello World
    Text (
    modifier = Modifier
    .border(


    width = 2.dp,


    color = Color.Green


    )


    .background(Color.Green),
    text = "Hello World"
    )
    .padding(10.dp)
    Modifiers

    View Slide

  33. h
    tt
    ps://developer.android.com/jetpack/compose/modi
    fi
    ers-list

    View Slide

  34. Layouts

    View Slide

  35. Column

    View Slide

  36. Column {
    }
    Column

    View Slide

  37. Column {


    Text ( "Hello


    Text ( "Hello


    Text ( "Hello


    }
    World" )


    World" )


    World" )
    Hello World


    Hello World


    Hello World
    Column
    Column {
    }

    View Slide

  38. Column(


    verticalArrangement =
    )


    }
    {
    X
    Y
    Column
    Arrangement.Center

    View Slide

  39. Hello World


    Hello World


    Hello World
    Column
    Column(


    verticalArrangement =
    )


    }
    {
    Arrangement.SpaceBetween

    View Slide

  40. Column(


    horizontalAlignment =
    )


    }
    {
    X
    Y
    Column

    View Slide

  41. Hello World


    Hello World


    Hello World
    Column
    Column(


    horizontalAlignment =
    )


    }
    {
    Alignment.End

    View Slide

  42. Column
    Column(


    horizontalAlignment =
    )


    }
    {
    Alignment.CenterHorizontally Hello World
    Hello World


    Hello World

    View Slide

  43. Row

    View Slide

  44. Row {
    Text ( “Hello" )


    Text ( "World" )


    Text ( “!" )
    HelloWorld!
    }
    Row

    View Slide

  45. Row(


    horizontalArrangement =
    )


    }
    {
    X
    Y
    Row

    View Slide

  46. Hello World !
    Row
    Row(


    horizontalArrangement =
    )


    }
    {
    Arrangement.SpaceBetween

    View Slide

  47. Row(


    verticalAlignment =
    )


    }
    {
    X
    Y
    Row

    View Slide

  48. HelloWorld!
    Row
    Row(


    verticalAlignment =
    )


    }
    {
    Alignment.CenterVertically

    View Slide

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

    View Slide

  50. Row & Column

    View Slide

  51. Row {


    Image(…)
    }
    Row & Column

    View Slide

  52. Row {


    Image(…)


    Column {
    }
    }
    Row & Column

    View Slide

  53. Row {


    Image(…)


    Column {


    Text ( “…” )


    Text ( “…” )


    }


    }
    Row & Column

    View Slide

  54. Box

    View Slide

  55. Box {


    Image(…)
    }
    Box

    View Slide

  56. Box {


    Image(…)


    Column {


    Text(…)


    Text(…)


    }
    }
    Box

    View Slide

  57. Box
    }
    Box
    {


    Image(…)


    Column(Modifier.align(Alignment.BottomEnd)) {


    Text(…)


    Text(…)


    }

    View Slide

  58. List

    View Slide

  59. fun EmployeeListView (items: List) {
    LazyColumn {
    }
    }
    List
    @Composable

    View Slide

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


    items (items) { item ->
    }
    }
    }
    List

    View Slide

  61. @Composable
    fun EmployeeListView (items: List) {
    LazyColumn {


    items (items) { item ->
    ItemRow(item)
    }
    }
    }
    List

    View Slide

  62. Slot Layouts

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  66. ● Column
    ● Row
    ● Box
    ● Sca
    ff
    old
    Layouts

    View Slide

  67. Layout modifiers

    View Slide

  68. Layout modifiers

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  73. State management

    View Slide

  74. ● Setup state using mutableStateOf
    State management

    View Slide

  75. 0
    + -
    State management

    View Slide

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

    View Slide

  77. Column {


    Text (


    text = counter.toString()
    0
    )
    ...
    }
    State management

    View Slide

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

    View Slide

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

    View Slide

  80. Composable UI-Redraw
    Event
    Recomposition

    View Slide

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

    View Slide

  82. Search
    State management

    View Slide

  83. View Model
    Event
    Search
    Search View
    State management

    View Slide

  84. SideEffects

    View Slide

  85. ● Work outside of composable function
    ● Open new screen when tapping bu
    tt
    on
    ● Show no network message
    SideEffects

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  95. DisposableEffect
    ● Calls onDispose on terminate
    @Composable
    fun HomeView() {
    DisposableEffect (...) {
    onDispose {
    callback.remove()
    }
    }
    }

    View Slide

  96. 101

    View Slide

  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")


    }


    }


    }


    }


    View Slide

  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")


    }


    }


    }


    }


    View Slide

  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")


    }


    }


    }


    }


    View Slide

  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")


    }


    }


    }


    }


    View Slide

  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")


    }


    }


    }


    }


    View Slide

  102. Composable
    @Composable


    fun Greeting(name: String) {


    Text(text = "Hello $name!")


    }


    @Preview(showBackground = true)


    @Composable


    fun DefaultPreview() {


    NotesApplicationTheme {


    Greeting("Android")


    }


    }

    View Slide

  103. Demo
    https://developer.android.com/codelabs/jetpack-compose-basics

    View Slide

  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

    View Slide

  105. Thats all folks!
    https://linktr.ee/aldefy

    View Slide