Building UI using Jetpack Compose in Android

In the android world, we use LinearLayout, Relative layout and what not to design the UI. Then we started using ConstraintLayouts to design UIs. But we still missed the trick to designing declarative UI in Android. We had a lot of different libraries to do it, but none of them had a native Android Support.

In Google IO '19, Google launched Jetpack Compose to create declarative UI. So, basically, declarative UI means to create UI by specifying a specific set of UI elements we need and to structure it some way.

So, let's discuss one by one about how we can use the jetpack compose.

PS : You should be on 4.1 Canary build of Android Studio

Step 01. Setup

add google() to project's build.gradle file

allprojects {
    repositories {
        google()
        jcenter()
    }
}

Step 02. App's Gradle

android {
    defaultConfig {
        ...
        minSdkVersion 21
    }

    buildFeatures {
        // Enables Jetpack Compose for this module
        compose true
    }
    ...

    // Set both the Java and Kotlin compilers to target Java 8.

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Step 03. Project's gradle file

dependencies {
    classpath 'com.android.tools.build:gradle:4.0.0-alpha01'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.60-eap-25"}

Step 04. Finally, Add Project dependency

implementation "androidx.compose:compose-runtime:0.1.0-dev02"
implementation "androidx.ui:ui-core:0.1.0-dev02"
implementation "androidx.ui:ui-layout:0.1.0-dev02"
implementation "androidx.ui:ui-framework:0.1.0-dev02"
implementation "androidx.ui:ui-material:0.1.0-dev02"
implementation "androidx.ui:ui-foundation:0.1.0-dev02"
implementation "androidx.ui:ui-text:0.1.0-dev02"
implementation "androidx.ui:ui-tooling:0.1.0-dev02"

Now, we are done setting up the project.Let's build the UI.Till now, we use setContentView to inflate the layout from an XML file. But in this tutorial, we are going to use Jetpack compose to design the layout file.

Step 05. In your Activity File,

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        //your design 
    }
}

Now, we set the design in setContent. Here we call a function. We use composable functions. So, as a developer let's start with Hello World.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}

Step 06. Let's discuss how to create a composable function.

to create a composable function we need to use @Composable annotation.

@Composable
fun helloWorld() {
    Text(text = "Hello World")
}

and call helloWorld() in setContent{}

  • Composable functions can be only called from another Composable function.

Step 07. Let's define a container.

Here if we need to have a behavior in LinearLayout with orientation in vertical mode. Here, we use Container,

Column {
    //the inside widgets
}

This will stack the elements in Linear layout in vertical order. In this let's discuss with an example of buttons,

Column {
    Button(
        text = "This is Button 1",
        onClick = {
            //the click listeners
        },
        style = ContainedButtonStyle()
    )
    HeightSpacer(32.dp)
    Button(
        text = "This is Button 2",
        onClick = {
            //the click listeners
        },
        style = OutlinedButtonStyle()
    )
}

Here, we have designed two different types of button

  • ContainedButtonStyle() - this will build a button with filled colors in the material design button.
  • OutlinedButtonStyle() - this will only have an outline button with white color filled

Output

  • we can also have TextButtonStyle() where we just have text in the button.

If we want to take design of Material design principle in android, we can use MaterialTheme()

MaterialTheme {
    // Widgets 1
    // Widgets 2
    // Widgets 3
}

Step 08. Let's discuss how to build a list using Jetpack Compose,

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        createListView()
    }
}

Here, createListView is a composable function. and in that, we define the list items.

@Composable
private fun createListView() {
    MaterialTheme {
        VerticalScroller {
            Column {
                (0..10).forEachIndexed { index, _ ->
                    createListItem(index)
                    Divider(color = Color.Blue, height = 1.dp)
                }
            }
        }

    }
}

Now, in this, let's discuss one by one.

  • MaterialTheme - this will define the theme of view taking material container
  • VerticalScroller - In basic term, this helps in the scrolling of the list items
  • Column - It creates a column to create and stack all the item in listview vertically. In that, we create 10items using forEachIndexed and we call createListItem index composable function to create list items specifically.

Now, createListItem looks like

@Composable
private fun createListItem(itemIndex: Int) {
        Padding(left = 8.dp, right = 8.dp, top = 8.dp, bottom = 8.dp) {
            FlexRow(crossAxisAlignment = CrossAxisAlignment.Center) {
                expanded(1.0f) {
                    Text("Item $itemIndex")
                }
                inflexible {
                    Button(
                        "Button $itemIndex",
                        style = ContainedButtonStyle(),
                        onClick = {
                            Toast.makeText(
                                this@MainActivity,
                                "Item name $itemIndex",
                                Toast.LENGTH_SHORT
                            ).show()
                        })
                
            }
        }
    }
}

In this, we add specify padding with 8dp unit from all end using Padding and then we create a FlexRow.

  • FlexRow is like a column but in this, it stacks the elements in a horizontal orientation.
  • crossAxisAlignment here specifies the alignment of the children.
  • expanded is like weight and in that we create a Text.
  • inflexible is like wrap_content, and in this we create a Button in each item having a click listener.

Now, let's run the app and see the preview

We are done creating a list in Jetpack Compose.

Miscs

  • to create a Alert Dialog we use,
AlertDialog(
    onCloseRequest = {
       //closing request
    },
    title = {
        Text("Title of Alert Box")
    },
    text = {
        Text("Message of Alert Box")
    },
    confirmButton = {
        Button(
            text = "OK",
            onClick = {
                //click listeners request
            }
        )
    }
)

Here, onCloseRequest is like setCancelable and rest is like to fill the data.

  • To design a floating action button we use
FloatingActionButton(
    icon = imageFromResource(resources, R.drawable.ic_add),
    color = //color,
    onClick = {
        // TODO click action
    }
)
  • To create a progress bar we use,
CircularProgressIndicator() //a circular progress bar

and

LinearProgressIndicator() //a horizontal progress bar
  • To see the preview of the composable function, we do it using ,
@Preview
@Composable
private fun helloWorld() {

}

you can see we are using Preview annotation to check the preview of composable functions.

This is how we can work around with Jetpack Compose. To read more about it try https://developer.android.com/jetpack/compose.

Happy learning

Team MindOrks :)

Also, Let’s connect on Twitter, Linkedin, Github, and Facebook