I started to write an introductory book on Jetpack Compose but couldn’t keep up with the rapid changes in the Compose tooling, so I am condensing and publishing the few chapters I have written for free. Here is what would have been chapter 1 of the book.
Few professional careers get more complex as their tooling improves, as does Android development. We live in a world with high dependency on mobile apps, and with that dependency comes high user expectations. Users expect mobile apps to be snappy, stable, self-descriptive, stylish, and have superpowers. It turns out that users do not want to read guides or manuals to use your app, and almost every user has tried to make an app do more than the app is designed to do.🦸 To respond to these growing user expectations and the competitive landscape, platform owners such as Google have made massive investments in and delivered tools such as Jetpack Compose to help developers deliver modern Android apps with impressive UI. There is only one problem – these tools are challenging to adopt!
This is an exciting time to be an Android developer. The introduction of Jetpack Compose is unlocking lots of opportunities to greatly improve developer productivity and deliver apps with an elegant user interface that meets end-user expectations. Most importantly, Jetpack Compose brings an excellent opportunity for professional growth. When you become proficient with Jetpack Compose, you will increase your appreciation and mastery of Kotlin language features and APIs, reactive programming paradigms, user-driven UI development, state management and re-think your understanding of the concept of separation of concern.
Adopting Jetpack Compose is not a cakewalk. This is not a Java to Kotlin transition, this is a paradigm shift, and this book is a practical guide to help you make that shift. This book is divided into four parts: The Basics, Todo List App, Chat App, and Testing. This chapter is a quick introduction to Jetpack Compose, followed by a list o key concepts and keywords you will encounter in Compose land.
Introduction to Jetpack Compose and its Benefits
Jetpack Compose is Android’s new toolkit for creating a modern Android app’s user interface (UI). It is more than a UI toolkit. It introduces a declarative paradigm to Android app development and simplifies Android app development, thereby improving developer productivity. Gone are the days of XML layouts and manually updating views. With Jetpack Compose, you can now build your app UI using Kotlin code. It’s declarative, which means you can define your UI as a set of composable functions that take in data and emit UI elements. This approach simplifies UI development, making it faster and more efficient.
But what makes Jetpack Compose so great? For one, it’s a modern UI toolkit that follows the latest UI design principles, such as Material Design. It’s also built with performance in mind, which means your app’s UI will be faster and smoother than ever before. Another big benefit of Jetpack Compose is that it integrates seamlessly with the rest of the Jetpack libraries. This means you can easily use features like ViewModel, LiveData, and Navigation with Compose, making it easier to build robust, scalable apps.
Jetpack Compose Key Terms
Jetpack Compose and Android development is littered with terms and acronyms. Over time, these will become part of your vocabulary. Below is a list of twenty Jetpack Compose terminologies and quick introductions that I believe will help you start Jetpack Compose right. We will cover each of these terms in-depth in the coming Days.
- Composable – Composable functions are the building block of Jetpack Compose. The UI is created in functions that do not return a value. Instead, they write to the screen whatever is described in that function. These functions are annotated with @Composable annotation and must be called from another Composable.
- Built-in Composables -The onCreate of a Composable Activity has a setContent Composable block which can serve as an entry point to your first Composable function and from there, you can call other Composable functions. So what Composables do you call from here? So what composables do you call from the onCreate … your own Composables! And in case you are not ready with your own composable functions, Jetpack is here for the rescue in that it provides you with ready-to-go composables such as Text, Image, Icon, and various layouts such as Column, Row, and Box. Speaking of Column…
- Column – this built-in composable is used to place items vertically on the screen. Think FrameLayout or LinearLayout on the Android XML layout system. This is one of the most commonly used layout/composables in Jetpack Compose. You will be using this a lot.
- Row – this built-in composable is used to place items horizontally on the screen. It’s like a LinearLayout with a horizontal orientation.
- Box – this built-in composable can be likened to a FrameLayout. Just like a Framelayout, the Box is used to display children related to their parent’s edges. The children of the Box layout will be stacked over each other. You can use the align modifier to specify where the composable should be drawn.
- ConstraintLayout – is a layout that allows you to place composables relative to other composables on the screen. It arranges items relative to one another. It provides an alternative to using multiple nested Column, Box, & Row and custom layout elements.
- LazyColumn – this is Jetpack Compose equivalent of RecyclerView. It provides a vertically scrolling list that only lays out the currently visible items. No more ViewHolder classes, LazyColumns are the ultimate time and space savers.
- LazyRow – this less-used composable lays out its children horizontally. Think of Recyclerview with a Horizontal Layout Manager in the legacy Android View system.
- Preview – adding @Preview annotation to @Composeable functions allows you to view the output of any Composable called within that Preview function right on Android Studio without running the composable on an Emulator or device. This Jetpack Compose ability speeds up development time because you can quickly see your changes almost in real time as you code. Moreover, Preview lets you render composable for different devices, group multiple compose, specify different themes and orientations, and much more.
- Surface – is Jetpack Compose equivalent of CardView in XML. It is an implementation of the Material design surface and is responsible for providing clipping, elevation, and borders to its children. It also blocks touch propagation behind it. Using Surface makes the code easier and indicates that you are using material design.
- Scaffold – A Scaffold implements the basic material design and visual layout structure. It can be likened to the Bootstrap template for Android UI, it has placeholders known as slots for AppBar (Top and Botton), NavigationDrawer, and FloatingActionButton (FAB). Scaffold ensures that these components will be positioned and work together correctly.
- Theme – The core element for implementing theming in Jetpack Compose is the MaterialTheme composable. To centralize your styling you create your own composable that wraps and configures MaterialTheme. By default, you get basic implementations of color, typography, and shape systems. However, you can modify or add your own custom systems to the default Theme object if needed.
- MaterialTheme – is a systematic way to customize Material Design to better reflect your product’s brand. A Material Theme contains color, typography, and shape attributes. When you customize these attributes, your changes are automatically reflected in the components you use to build your app. Jetpack Compose implements these concepts with the MaterialTheme composable.
- Modifier – Modifiers are used to modify how a Composable is laid out or behaves in a very flexible way. To set modifiers, a Composable needs to accept a modifier as a parameter and by convention, the modifier is specified as the first optional parameter of a function. This way you can specify a modifier on a composable without having to name all parameters. You will love Modifiers!
- State – Let’s say the time is 10.00 am and you display that value with a Text composable on the screen. Jetpack Compose has a built-in mechanism for you to continually update that value as the time increments. This mechanism is known as State management. A State in Jetpack Compose, therefore, is any value that can change during the execution of your app. All composables are not required to have state. A stateless composable is a composable that cannot directly change any state while a stateful composable is composable that owns a piece of state that can change over time. State is essential in working with Compose.
- Recomposition – when a state value changes, Jetpack updates the UI through a process called recomposition. The whole concept of thinking in Compose depends on your understanding of recomposition. Imagine a step counter app with a single screen that shows the number of steps in the format “Number of Steps = 123”. Jetpack Compose will continually recompose to update the UI as long as you provide it the value of the steps as an observable. And if you do, Jetpack Compose is smart enough to only update the value 123 as that is the only thing that changes and not update the value “Number of Steps = “
- Hoisting – State hoisting is the pattern of moving a state up to make a component stateless. Let’s put this into a little context; continuing with the step counter app, we can write our composable to simply accept the step value as a state even if we provide an input in that Composable that allows the user to enter their step. The general approach with state hoisting in composing is to replace the value of the state (in this case, the count of steps) with two parameters. The value: T, which is the number of steps to display, and an onValueChange: (T) → Unit, which is an event that requests the value to change.
- Side Effect – A side effect is any changes that are visible outside of the execution of a composable function. A composable function that displays a list of to-do items in a to-do list should do just that – display an item. Since most to-do items have a checkbox next to the name of the item, the composable displaying that item should not have the side effect of handling when the checkbox is checked or unchecked.
- NavController – manages app navigation within a NavHost. It is the main object in a Navigation Component. There is a subclass called NavHostController which provides additional APIs such as setOnBackPressedDispatcher that are needed for Compose navigation. The same principles of implementing navigation with Fragments apply to Composing navigation. However, there are new concepts, such as routes that are native to Compose.
- NavHost – it is the object that manages the real estate under navigation. Let’s use the concept of a property manager to understand NavHost. Let’s assume you have a multi-story building, and you decide to occupy the base floor and top floors and hand over the other floors to a property management company to manage. You can now think of this section of the building under management as being wrapped with a NavHost that can swap in and swap out tenants or screens as needed using the NavController you passed to it. The top and basement floor can be likened to the Top and Bottom Appbars, which we will learn about later in this section.
Jetpack Compose is the most transformative development to come to Android development since the adoption of Kotlin as the official language. It simplifies UI development and brings Android forward to the declarative UI development paradigm. You will see noticeable productivity gain once you transition to the Compose way of thinking. It’s not just a UI toolkit, it’s the future of Android development, and every developer should start working with it. Today we learned about this book structure, looked at some benefits of Jetpack Compose, and some key terms and concepts you will run into regularly in your composition journey.