What is Jetpack Compose?

Recently, we wrote about the demonstrative move to declarative UI. With Jetpack Compose, Android is joining the declarative trends.

Jetpack Compose is a new declarative UI toolkit by Google made for building native Android apps that is rapidly gaining traction. In contrast to the traditional XML Views, Jetpack Compose allows you to build UIs using composable functions that describe how the UI should look and behave.

The main advantage of using Jetpack Compose is that it allows you to write UI code that is more concise and easy to understand. This leads to improved maintainability and reduced development time.

The main disadvantage of using Jetpack Compose is that it’s relatively new, so its ecosystem is limited compared and the number of available libraries, tools, and resources is lower than the traditional ecosystem.

Despite that, Jetpack Compose’s ability to be integrated into existing Android apps and be gradually adopted has made its way into countless apps. Some of the bigger and more popular apps that started adopting Jetpack Compose include Lyft, Twitter, Airbnb, Square, Reddit, and Firefox.

How to start using Jetpack Compose?

The recommended IDE for working with Jetpack Compose is Android Studio. After downloading and installing Android Studio, you’ll get the option to create a new project. To create a new Jetpack Compose application, you need to select either the Empty Compose Activity (which uses Material v2 which is more stable), or Empty Compose Activity (Material3) (which uses the Material v3 which is still in Preview). You can see both options in the top right of this screenshot:

Untitled

This is the easiest way to get started with Jetpack Compose. If you’d like to enable Jetpack Compose into an existing Android application, here’s what you need to do:

  1. Add the following build configurations in your app’s build.gradle file:

    android {
        buildFeatures {
    				// this flag enables Jetpack Compose
            compose true
        }
    
        composeOptions {
    				// the compiler version should match
    				// your project's Kotlin version
            kotlinCompilerExtensionVersion = "1.3.2"
        }
    }
    
  2. Add the Compose BOM (Bill of Materials) and the subset of Compose dependencies to your dependencies:

    dependencies {
        def composeBom = platform('androidx.compose:compose-bom:2022.12.00')
        implementation composeBom
        androidTestImplementation composeBom
    
        // Choose one of the following:
        // Material Design 3
        implementation 'androidx.compose.material3:material3'
        // or Material Design 2
        implementation 'androidx.compose.material:material'
        // or skip Material Design and build directly on top of foundational components
        implementation 'androidx.compose.foundation:foundation'
        // or only import the main APIs for the underlying toolkit systems,
        // such as input and measurement/layout
        implementation 'androidx.compose.ui:ui'
    
        // Android Studio Preview support
        implementation 'androidx.compose.ui:ui-tooling-preview'
        debugImplementation 'androidx.compose.ui:ui-tooling'
    
        // UI Tests
        androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
        debugImplementation 'androidx.compose.ui:ui-test-manifest'
    
        // Optional - Included automatically by material, only add when you need
        // the icons but not the material library (e.g. when using Material3 or a
        // custom design system based on Foundation)
        implementation 'androidx.compose.material:material-icons-core'
        // Optional - Add full set of material icons
        implementation 'androidx.compose.material:material-icons-extended'
        // Optional - Add window size utils
        implementation 'androidx.compose.material3:material3-window-size-class'
    
        // Optional - Integration with activities
        implementation 'androidx.activity:activity-compose:1.5.1'
        // Optional - Integration with ViewModels
        implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
        // Optional - Integration with LiveData
        implementation 'androidx.compose.runtime:runtime-livedata'
        // Optional - Integration with RxJava
        implementation 'androidx.compose.runtime:runtime-rxjava2'
    
    }
    

How do you build UI in Jetpack Compose?

Jetpack Compose uses Composables to define the view hierarchy, and modifier to apply visual appearance and behavior changes to the composables they’re added to.

Composable functions

Composable functions (or just Composables) are ordinary Kotlin functions that are annotated with @Composable, can be nested within another composable functions, and return a hierarchy of other composables in order to define their UI. Let’s see a simple composable that defines a contact row UI that contains a user photo, and a name and phone number:

@Composable
fun ContactRow(user: User) {
	Row {
		Image (
			painter = painterResource(id = R.drawable.user),
			contentDescription = "A photo of a user"
		)

		Column {
			Text(user.name)
			Text(user.phone)
		}
	}
}

The Row composable is a layout composable that renders its children one next to another. The Image composable is the first child which is going to render the user drawable. Then we have the Column composable which, similar to the Row, is a layout composable, but it renders its children one below another. The children of the Column composable are two Text composables that render the user’s name and phone number.

Modifiers