In the dynamic realm of Android app development, it is not uncommon for new libraries, SDKs, and architectures to rise and fall and new features to get added or removed each year. Among the few things to survive the flux, the XML-based UI toolkit is relied on by developers to build user interfaces of all kinds. It is a bit of a tedious process: UI layouts are defined in an XML file, accessed and processed inside Kotlin files.

That normal is now slowly changing. Declarative and reactive UI toolkits and frameworks are shaking things up. 

Facebook was among the first to make a foray into the field with Litho (for Android) and ComponentKit (for iOS) albeit without much success. Enter ReactNative and Flutter, and developers have started developing apps faster with far less code. The excitement went up when, in 2019, Apple introduced SwiftUI

One month ago, Google announced the alpha version of Jetpack Compose. The most compelling reason: developers love writing declarative UIs.

Google's announcement says, “Finally, we heard strong feedback from the community that developers like the simplicity of declarative APIs for building UI.”

Wait, What’s a “Declarative UI”?

A declarative UI pattern defines the UI as a function of the “state.” A “state” is nothing but a variable or an object that holds a value, which can change based on user input or other business logic. When the state changes, the framework will redraw the UI.

UI = f(state)

You don’t have to manually modify the UI to reflect the new state. Instead, you can declare what to show in each state and the framework will show the matching UI for the current state. It is called “reactive UI” because the UI “reacts” to state changes.

If you are switching from imperative to declarative for the first time, you may find this part tricky as the new paradigm demands a thought process radically different from what you are accustomed to. It may take a while for the declarative style of thinking to click into place, but once it does, it will stay put for good.

You may have seen declarative UI described in different ways, but this is how I explain it to people: when we write a declarative UI, we tell the computer “which UI to show for this value” instead of “how to show a UI for this value.”

Here’s a simple example in pseudo code. When a user types their name into a text input field, the label field should show “Welcome, $name” in blue. If the name is empty, then it should show “Welcome, Guest” in black.

Imperative UI

TextInput input = find_from_UI()
Label label = find_from_UI()

label.setFont("Helvetica")
label.setColor(BLACK)
label.setText("Welcome, Guest")

input.setHint("Enter your name")
input.setFont("Helvetica")
input.onChange((text) {
   if(text is empty){
      label.setText("Welcome, Guest")  // requires manually updating the UI
      label.setColor(BLACK)
   } else {
      label.setText("Welcome, $text")
      label.setColor(BLUE)
   }
})

Declarative UI

State name = State<String>()

Label(
 text: "Welcome, ${ if(name is empty) "Guest" else name }",
 color: if(name is empty) BLACK else BLUE,
 font: "Helvetica"
)

TextInput(
  hint: "Enter your name",
  font: "Helvetic",
  onChange: (text){ 
    name=text   // just update the state, the framework will update the UI
  }
)

In the imperative UI, you have to manually update the text and color of the label when the user types a text. But in the declarative UI, you only have to update the state. The framework will do the job of updating the text and color of the label for you.

Tell Me More About Jetpack Compose.

Jetpack Compose is a modern declarative UI toolkit that simplifies native UI development across all Android platforms. It is the Android team’s take on the revolutionary declarative paradigm. Google announced Jetpack Compose during IO 2019 and released alpha in August 2020.

Compose is an unbundled library, that is, it is not linked to any OS. All UI components in Compose are built from scratch and exist independent of the existing native UI elements. For example, a button in Compose doesn't use the native Android “Button” class under the hood; instead, it literally paints a button on the screen.

I Know the XML Way. Why Should I Learn Compose?

You can continue using the XML-based UI toolkit—it’s not going to disappear anytime soon. But do you really want to miss the ease of writing less code and speeding up app development? If I were to compare Compose vs XML, Compose is the clear winner. 

Here are five reasons why I think you should learn Compose: 

1. Easy UI Management: Currently, keeping the app state and the UI state in sync is a hassle considering how you have to manually update all the UI components to reflect the changes in the app state. Tediousness apart, the process introduces unintended bugs. Compose does away with this step of manual synchronization. It automatically updates the UI to match the state. 

2. Kotlin for UI and Logic: To develop XML-based UIs, you must maintain two files—an XML file for layout and a Kotlin file for Activity or Fragment. Compose eliminates the need for a separate file for the UI layout. It allows you to write UI elements within the Activity or Fragment using Kotlin. Compose is built using Kotlin, so you don’t have to learn another language to use Compose.

3. Independent of the OS: The current UI components are tightly bound to the OS platform. When you create a “Button” in XML, it may look different on different OS versions and devices. Also, since these components are bundled with the OS, new fixes and improvements require another release of the OS. In Compose, every UI element is built from scratch, independent of the underlying OS. For example, a “Button” in Compose looks and behaves the same on all devices. 

4. Interoperability: Compose supports interoperability, which means developers can use Compose within projects that use XML layouts. It can reuse the existing XML layouts to build UIs. Also, Compose can work with the existing ViewModel objects, LiveData, Flow, and Observables so that you don’t have to modify the existing ViewModels to use Compose.  

5. Less code, faster development: Currently, you have to write a lot of code to manage the UI—from setting contents, defining themes, and positioning components to managing visibility based on the business logic. This steals a lot of development time for polishing the UI and debugging other UI issues. In Compose, you can declare UIs directly within the Kotlin files. It eliminates the need to maintain separate XML files and handle them in the code. This means less code and faster development.

My favorite part is that Compose is reactive and declarative. After several years of native Android app development, I worked with Flutter lately and fell in love with it instantly. The most adorable feature of Flutter is the reactive, declarative UI pattern that eliminates a lot of pain points that I come across when writing apps in the native framework. Since I don’t have to manage the UI myself, I can concentrate more on the business logic than debugging UI issues.

So, Will Our Next Project Use Compose?

Not yet. Not until 2021, at least.

Compose is still in alpha stage and not yet production-ready. It is expected to be stable by 2021.  

Compose doesn’t have a navigation component yet to support navigation between screens. The APIs may keep on changing or be replaced before production release. So, using Compose in a production app is not yet recommended. 

But once it’s here, you can be sure it will spur our mobile app development in the declarative direction.

What’s Next?

Jetpack Compose will definitely make a huge difference to native Android app development, bringing the developer experience close to other declarative UI frameworks like SwiftUI and Flutter.

Since Compose is independent of the underlying OS, it has the potential to work on multiple platforms without any OS-level dependencies. There is a high chance for Compose joining hands with Kotlin Multiplatform to build the next-generation cross-platform application development toolkit.

The shift towards the declarative UI paradigm is inevitable. I believe the new decade is going to belong to declarative UI in the realm of mobile, web, and desktop app development. 

So developers, let’s prepare early for the age of declarative UI toolkits.


Additional Resources: Google’s course on Jetpack Compose is a good starting point. There are also sample projects from Google. You will need to install Android Studio 4.2 latest Canary build to run them.

No Image
Solutions Architect