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

Jetpack compose for beginners

Jetpack compose for beginners

Karan Dhillon

July 23, 2021
Tweet

More Decks by Karan Dhillon

Other Decks in Technology

Transcript

  1. Jetpack compose is Android’s modern toolkit for building native UI.

    Simpli f ies and accelerates UI development on Android by writing less code. As app state changes, your UI automatically changes. Written in Kotlin. WHAT IS JETPACK COMPOSE?
  2. Building block of jetpack compose. Just like a regular function,

    but annotated with @Composable. This enables your function to call other @Composable functions within it. Able to make generic containers, that can take another @Composable functions as parameters. COMPOSABLE
  3. COMPOSABLE @Composabl e fun Greeting(name: String) { Text(text = "Hello

    $name!" ) } class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { Surface(color = MaterialTheme.colors.background) { Greeting("360|AnDev" ) } } } } } Instead of passing XML as you’d do in traditional View system, you call Composable functions within it.
  4. MODIFIERS @Composabl e fun Greeting(name: String) { Surface(color = Color.Yellow)

    { Text ( text = "Hello $name!" , modi fi er = Modi fi er.padding(24.dp ) ) } }
  5. MODIFIERS Some common Modi f iers are: clickable Padding Background

    Alpha f illMaxSize onKeyEvent Scale rotate Chaining Modi f iers.
  6. MODIFIERS @Composabl e fun Greeting(name: String) { Surface(color = Color.Yellow)

    { Text ( text = "Hello $name!" , modi fi er = Modi fi e r .padding(24.dp ) .background(color = Color.Yellow, shape = RectangleShape ) .clickable { Toast.makeText ( this , "Click event" , Toast.LENGTH_SHORT ).show( ) } . fi llMaxSize( ) ) } }
  7. MODIFIERS @Composabl e fun Greeting(name: String) { Surface(color = Color.Yellow)

    { Text ( text = "Hello $name!" , modi fi er = Modi fi e r .padding(24.dp ) .background(color = Color.Yellow, shape = RectangleShape ) .clickable { Toast.makeText ( this , "Click event" , Toast.LENGTH_SHORT ).show( ) } . fi llMaxSize( ) ) } }
  8. MODIFIERS @Composabl e fun Greeting(name: String) { Surface(color = Color.Yellow)

    { Text ( text = "Hello $name!" , modi fi er = Modi fi e r .padding(24.dp ) .background(color = Color.Yellow, shape = RectangleShape ) .clickable { Toast.makeText ( this , "Click event" , Toast.LENGTH_SHORT ).show( ) } . fi llMaxSize( ) ) } }
  9. MODIFIERS @Composabl e fun Greeting(name: String) { Surface(color = Color.Yellow)

    { Text ( text = "Hello $name!" , modi fi er = Modi fi e r .padding(24.dp ) .background(color = Color.Yellow, shape = RectangleShape ) .clickable { Toast.makeText ( this , "Click event" , Toast.LENGTH_SHORT ).show( ) } . fi llMaxSize( ) ) } }
  10. COLUMN @Composabl e fun Greeting() { Surface(color = Color.Yellow) {

    Column { Text(text = "Android" ) Divider(color = Color.Black ) Text(text = "loves compose" ) } } }
  11. ROW @Composabl e fun Greeting() { Surface(color = Color.Yellow) {

    Row(modi fi er = Modi fi er. fi llMaxWidth()) { Text ( text = "Android" , modi fi er = Modi fi er.background(color = Color.Red ) ) Text(text = "loves compose" ) } } }
  12. LAZYCOLUMN(LAZYROW) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { NameList ( listOf ( "Hello Android 1" , "Hello Android 2” , … ) ) } } } @Composabl e fun NameList(dataSet: List<String>) { LazyColumn { items(dataSet) { item - > Greeting(name = item ) } } } }
  13. LAZYCOLUMN(LAZYROW) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { NameList ( listOf ( "Hello Android 1" , "Hello Android 2” , … ) ) } } } @Composabl e fun NameList(dataSet: List<String>) { LazyColumn { items(dataSet) { item - > Greeting(name = item ) } } } }
  14. LAZYCOLUMN(LAZYROW) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { NameList ( listOf ( "Hello Android 1" , "Hello Android 2” , … ) ) } } } @Composabl e fun NameList(dataSet: List<String>) { LazyColumn { items(dataSet) { item - > Greeting(name = item ) } } } }
  15. STATE @Composabl e fun Counter() { val count = remember

    { mutableStateOf(0) } Button(onClick = { count.value++ }) { Text("I've been clicked ${count.value} times" ) } }
  16. STATE HOISTING @Composabl e fun Counter(count: Int, updateCount: (Int) ->

    Unit) { Button(onClick = { updateCount(count+1) }) { Text("I've been clicked $count times" ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { Surface(color = MaterialTheme.colors.background) { val counterState = remember { mutableStateOf(0) } Counter ( count = counterState.value , updateCount = { newCount - > counterState.value = newCoun t } ) } } } }
  17. STATE HOISTING @Composabl e fun Counter(count: Int, updateCount: (Int) ->

    Unit) { Button(onClick = { updateCount(count+1) }) { Text("I've been clicked $count times" ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState ) setContent { AndDev360Theme { Surface(color = MaterialTheme.colors.background) { val counterState = remember { mutableStateOf(0) } Counter ( count = counterState.value , updateCount = { newCount - > counterState.value = newCoun t } ) } } } }
  18. ANIMATION override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState ) setContent {

    AndDev360Theme { NameList(listOf ( "Hello Android 1" , "Hello Android 2” , … ) ) } } } @Composabl e fun Greeting(name: String) { var isSelected by remember { mutableStateOf(false) } val backgroundColor by animateColorAsState(if (isSelected) Color.Yellow else Color.Transparent ) Text ( text = "Hello $name!" , modi fi er = Modi fi e r .padding(24.dp ) .background(color = backgroundColor ) .clickable(onClick = { isSelected = !isSelected } ) ) }
  19. ANIMATION If animating appearance and disappearance, use AnimationVisibility. If crossfading,

    use Crossfade. If you want to animate multiple values, then use updateTransition, otherwise use animate*AsState.
  20. THEMING @Composabl e fun AndDev360Theme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable()

    () -> Unit) { val colors = if (darkTheme) { DarkColorPalett e } else { LightColorPalett e } MaterialTheme ( colors = colors , typography = Typography , shapes = Shapes , content = conten t ) }
  21. THEMING override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState ) setContent {

    AndDev360Theme { Greeting(name = "360|AnDev" ) } } } @Composabl e fun Greeting(name: String) { Text ( text = "Hello $name!" , modi fi er = Modi fi er.padding(24.dp) , style = MaterialTheme.typography.h 1 ) }
  22. ComposeView - To use jetpack compose in traditional UI system.

    AndroidView - To use traditional UI system in jetpack compose. INTEROPERABILITY
  23. COMPOSEVIEW <?xml version="1.0" encoding="utf-8"?> <LinearLayou t xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"

    > <TextVie w android:id="@+id/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello Android!" / > <androidx.compose.ui.platform.ComposeVie w android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" / > </LinearLayout> class ExampleFragment : Fragment() { override fun onCreateView ( in fl ater: LayoutIn fl ater , container: ViewGroup? , savedInstanceState: Bundle ? ): View { // In fl ate the layout for this fragmen t return in fl ater.in fl ate ( R.layout.fragment_example, container, fals e ).apply { fi ndViewById<ComposeView>(R.id.compose_view).setContent { // In Compose worl d MaterialTheme { Text("Hello Compose!" ) } } } } }
  24. COMPOSEVIEW <?xml version="1.0" encoding="utf-8"?> <LinearLayou t xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"

    > <TextVie w android:id="@+id/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello Android!" / > <androidx.compose.ui.platform.ComposeVie w android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" / > </LinearLayout> class ExampleFragment : Fragment() { override fun onCreateView ( in fl ater: LayoutIn fl ater , container: ViewGroup? , savedInstanceState: Bundle ? ): View { // In fl ate the layout for this fragmen t return in fl ater.in fl ate ( R.layout.fragment_example, container, fals e ).apply { fi ndViewById<ComposeView>(R.id.compose_view).setContent { // In Compose worl d MaterialTheme { Text("Hello Compose!" ) } } } } }
  25. ANDROIDVIEW @Composabl e fun CustomView() { val selectedItem = remember

    { mutableStateOf(0) } // Adds view to Compose AndroidView ( modi fi er = Modi fi er. fi llMaxSize(), // Occupy the max size in the Compose UI tree factory = { context - > // Creates custom view CustomView(context).apply { // Sets up listeners for View -> Compose communication myView.setOnClickListener { selectedItem.value = 1 } } } , update = { view - > // View's been in fl ated or state read in this block has been updated // Add logic here if necessary } ) }
  26. Jetpack compose docs (https://developer.android.com/jetpack/compose) API guidelines for Jetpack compose (https://github.com/androidx/androidx/blob/

    androidx-main/compose/docs/compose-api-guidelines.md) Adopting Jetpack compose in your app(https://developer.android.com/jetpack/ compose/interop) RESOURCES