JetPack Compose: The Beginning
Introduction
Jetpack Compose was introduced around 2019, and ever since then, it has been growing very fast. Some developers have already started using it and are migrating some of their code to use compose. It’s 2022, if you are an Android developer and you haven’t started using compose, then you are missing a lot, and with the way it’s growing very fast, you will be left behind. I will be publishing more articles on Jetpack Compose. This article is going to be an introduction to Jetpack Compose.
In the beginning
When you want to create an Android app, after you create the project, navigate to the XML and add some XML attributes. Let’s assume we are adding a TextView inside a LinearLayout just like the screenshot below. The TextView has some properties like textSize, gravity, and textColor.
Next is to add some logic, navigate to your Kotlin or Java code, and do some logic. Here, I decided to make the TextView clickable. Once clicked, it should show the toast message “Hello World” (the screenshot below).
Now with Jetpack Compose, I don’t have to create up to two files (my XML code and Kotlin code). All I need to do is navigate to my Kotlin code and write some composable functions by getting rid of XML. Check out the screenshot below:
Are you still not convinced? Okay, if you are not convinced enough, go through the rest of the article. Like me, I saw Compose as a threat at first, but now I’m a fan.
Why Compose
- findViewById 😔
- databinding and viewbinding
- APIs are showing signs of Aging
- RecyclerView
- View Class keeps getting bigger and bigger
findViewById
findViewById
is the source of many user-facing bugs in Android. It’s easy to pass an ID that’s not in the current layout — producing null
and a crash. And, since it doesn’t have any type-safety built-in, it is easy to ship code that calls findViewById<TextView>(R.id.image)
.
The problem with using findViewById(id)
calls is that they feel needlessly tedious and can lead to runtime crashes.
databinding and viewbinding
Data binding and view binding are two different things, but they achieve the same goal.
- DataBinding approach needs you to add
<layout>
a tag to your XML layout to enable the data binding process; - ViewBinding doesn’t support layout variables or layout expressions, so it can’t be used to bind layouts with data in XML.
Issues with Data Binding When it was first released, you had to build your app for it to generate by converting the name of the XML file into camel case and adding the word “Binding” to the end. Imagine having about four modules in your app, and the specs of your laptop or PC are not that strong; you will spend minutes waiting for it to build.
To read more on Databinding and ViewBinding click here
APIs are showing signs of Aging
With time, all APIs start showing signs of aging. Popular programming concepts from ten years ago have been refined, and new paradigms have come to the fore. For example, the Android UI toolkit is heavily based on the inheritance concept of object-oriented programming, but even that classical concept is less prominent now. As APIs evolve, they accumulate what can be called "code cruft," like the anecdotal View class with its thirty thousand lines of code.
Before AndroidX was released, there was a lot of confusion when it came to the support library versioning. The naming was so messed up, especially when dealing with Fragments v13, v4, and v7, for example:
implementation ‘com.android.support:support-v13:28.0.0’
implementation ‘com.android.support:support-v4:28.0.0’
implementation ‘com.android.support:appcompat-v7:28.0.0’
RecyclerView
RecyclerView’s main idea is to provide listing functionality in a performance-friendly manner. The ‘Recycler’ part of this view’s name is not there by coincidence. The RecyclerView can recycle the items with which it’s currently working. The recycling process is done thanks to a pattern called View Holder. (We will talk more about this in the next Article)
The only challenge is that you have to create about four files just to display a list of items.
View Class keeps getting bigger and bigger
- View Class has over 31110 lines of code.
- All the Views (TextView, Button, ImageView, RadioButton etc.) inherit from the View Class.
- It becomes very difficult to maintain.
What is Compose
It's a modern toolkit for building native Android UI. It simplifies and accelerates UI development on Android with less code, powerful tools, and intuitive Kotlin APIs. In Compose, everything is a function.
Declarative UI
Declarative UI is a UI that’s designed in a declarative way. You describe what it should be like.
Differences between Declarative and Imperative
Declarative
- This pattern is an emerging trend that allows developers to design the user interface based on the data received.
- This design paradigm makes use of one programming language to create an entire application.
- This on the other hand focuses on the what
Imperative
- This is the most common paradigm; it involves having a separate prototype/model of the application’s UI.
- A good example is XML layouts in Android. We design the widgets and components which are then rendered for the user to see and interact with.
- This design focuses on the how rather than the what
Declarative UI in other frameworks
How it looks like in Compose
Some of Compose Components
- Layouts
○ Column
○ Row
○ Flex(column/row)
○ Box(similar to Framelayout)
○ ConstraintLayout - Built-in Components
○ Button
○ Text
○ Checkbox
○ Navigation Drawer
○ Navigation Bar
○ Scaffold
○ AppBar - Custom View
○ Layout
○ Draw
How to Get Started
There are two ways of getting started:
- Create a new Project
- Migrate your codebase to start using compose
Create a new Project
To create a new compose project navigate to files, hover over "New," click on "New Project," a dialog appears, and you choose "Empty Compose Activity," and you are good to go.
Migrate your codebase to start using compose
To migrate your app to start using compose, go through this codelab, which is very easy to use.
https://developer.android.com/codelabs/jetpack-compose-migration#0
Compose Basics
Like I said earlier, in Compose, everything is a function. It’s a regular function annotated with @Composable. It enables your function to call other @Composable functions within it.
One thing I love about Compose is that you can preview your changes without running the app on your phone by adding the @Preview annotation to your code.
Modifiers
are used to modify the composable UI elements, for example by adding margin, padding, or defining the width and height. Available modifiers are: background(), clickable, scrollable, draggable, swipeable, width(), height(), size(), padding(), and many more.
For example, the screenshot below uses one of the modifiers called padding:
Compose are reusable — State Hoisting
One of the principles in Jetpack Compose is to hoist
state — that is, to move a composable’s state outside of the composable and push it further up, making the composable stateless. Creating stateless composable results in components that are easier to reuse and test. Read more here
Column — Vertical Arrangement
A column is a layout composable that places its children in a vertical sequence. (I will explain more about this in my next article)
Row— Horizontal Arrangement
A row is a layout composable that places its children in a horizontal sequence. (I will explain more about this in my next article)
Lazy — Column
A LazyColumn is a vertically scrolling list that only composes and lays out the
currently visible items. It’s similar to a Recyclerview in the classic Android
View system. (I will explain more about this in my next article)
Conclusion
Jetpack Compose is moving fast. I will advise that you start looking into it as soon as possible because there are signs that it is going to replace the traditional way of building Android apps. I will be publishing more articles on Jetpack Compose, so stay tuned.
Thank you for reading this article. Be sure to clap and recommend this article if you found it helpful and insightful. It means a lot to me
Chat me up on Twitter or Linkedin