Jetpack Compose is a modern toolkit provided by Google to simplify UI development for Android. Launched in the summer of 2021, it’s part of an emerging trend of declarative UI frameworks that promise simpler, faster UI development by letting developers focus on “what” they want to create, rather than “how” to go about it.
As Navan’s Technical Android Lead, I’m always on the lookout for improved ways of working. But as any serial early adopter knows, sometimes in our eagerness to see what we can do with a new piece of tech we jump aboard too soon, before it’s fully baked.
I was keen to check out Jetpack Compose and see whether it lives up to the hype or still has a ways to go.
A quick primer for the unfamiliar: With Jetpack Compose, developers piece together (or “compose”) a UI like a Lego set, brick by brick, by calling pre-defined Compose functions into the UI hierarchy. The beauty of this approach is that when the source data changes, the entire framework re-executes and populates each element of the UI with the new data automatically.
Jetpack Compose is built around Kotlin, a concise and safe programming language that aids in increasing developer productivity by providing features of both object-oriented and functional programming. And Jetpack Compose leverages the special idioms that Kotlin provides, for example, specifying default values for function arguments, higher-order functions, and lambda expressions.
Compose functions — or “Composables” — look just like regular functions. They can create UI components or call other Composables, which allows for the creation of small and focused reusable components.
Here’s an example:
It’s relatively easy for the curious developer to dip their toe into Jetpack Compose by integrating it into an existing app. There are a couple of ways to go about this:
The example below lays out a simple way to build an entirely Compose-based screen, using the setContent() function:
The result:
I decided to experiment with Jetpack Compose by using it to build the new My Reimbursements screen within the TripActions Liquid app (now the Navan app).
Right off the bat, I was impressed with how easy it is to develop a list view. LazyColumn and LazyRow are equivalent to vertical and horizontal RecyclerView in XML — but they drastically reduce the amount of boilerplate code required.
Another plus: Creating a sticky header was a breeze. In XML, this would have required many lines of complex code. In Compose, I used the StickyHeader function in conjunction with groupBy, and only added about 10 lines of code.
The basic layouts available in Compose are the Column, Row and Box. For those familiar with LinearLayout in XML: Column and Row are akin to the Vertical and Horizontal orientations, and Box does the same job as FrameLayout.
Basic layouts available in Compose (“Compose Layout Basics” is licensed under CC BY-ND 2.5)
Here’s a simple example that uses Column:
For the majority of the layouts in My Reimbursements, I found Row and Column sufficient for placing UI elements where I wanted them. In the few instances where these fell short, I used Compose ConstraintLayout. If you’re familiar with the ConstraintLayout in XML, you’ll be in familiar territory here.
A look at the TripActions Liquid app (now the Navan app) with the sticky header, custom tab, and list view with paging.
I was also able to build in several more complex features, but I’ll admit these required a bit of digging! I used the Jetpack Compose Paging library to power the list view with paging and to interface with Reactive Extensions. I created a custom tab UI component to fulfill the creative vision of the UI design team to have a tall tab component to accommodate the departing, flying, landing, and the cute crashing money paper airplane, as seen below.
In addition, I used the Swipe Refresh library to build the pull-to-refresh feature for the list view, and the Pager Layouts library to achieve the effect of sliding pages under the four Tabs. These libraries are part of a group of libraries named Google Accompanist. Unfortunately, they’re only in experimental mode at this point, which means there’s no guarantee that they will make it into the main app software in the future.
Another drawback: the libraries are new, which means scant in-depth documentation and few community support references to turn to.
Jetpack Compose is the future of Android development and promises to simplify UI development drastically. And in many ways, the barrier to entry is low; you can get a feel for the software by simply adding just a little piece onto an existing app built in XML.
But developing and thinking in Compose is a paradigm switch that requires a measure of time and effort that not every team has to spare. With many libraries still in the experimental phase, there’s an element of building the plane while it’s flying…but for those who are prepared to roll up their sleeves, it could be a thrilling ride!