How to create realistic UI with Jetpack Compose(Part II)

Kruti Kamani
Jan 12 · 5 min read
Flower App

We have already given basic stuff related to Jetpack Compose in our previous blog Saying Hello to Jetpack Compose.

Jetpack compose is the new way to build UI for your android applications in a declarative manner. Now no more XML needed and you can build Android apps without construct the XML layout code.

Is it really possible to make UI design without XML??

Yes… You can do it with latest Jetpack Compose modern UI toolkit to make this thing possible. Using Compose, you can build your user interface by defining a set of composable functions that take in data and emit UI elements.

Key points of declarative UI pattern of Jetpack compose:

  • Accelerate development : It is fully compatible with your existing code.
  • Less Code : It does more with less code and avoids entire classes of bugs, so code is simple and easy to maintain.
  • Powerful Tools : You can create attractive apps with access to the Android platform APIs.
  • Intuitive : You just need to describe your UI and then Compose will take care of the rest. Every time the state changes, the UI automatically gets updated.

In this Article, we will create UI of Flower app from our Dribbble shots and will learn how to create simple UI with Jetpack Compose.
So without wasting your time let’s begin.

Quick Start

To get started with Jetpack Compose, a couple of Gradle dependencies need to be imported.

//App level build.gradle
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.ui:ui-tooling:$compose_version"

Also need to add the compose flag as true, in the buildFeatures block within android:

//App level build.gradle
buildFeatures {
compose true
}

The entry point to a Compose app

As Jetpack Compose exposes a programmatic way to build user interfaces, you won’t be using any XML. Instead of calling setContentView(R.layout.activity_main) you have to construct the setContent method.

class MainActivity : AppCompatActivity() {

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

setContent {
Text("Hello, World!")
}
}
}

Let’s create a flower list and showing basic information

If we need to design the UI with more elements, then will go with Linear layout, Relative layout or Constraint layouts to get the perfect design.

To achieve the same in Jetpack compose we have to use some specific containers. For example, Column is the one of the container.

Column { 
//Write your design here
}

As the name of the function describes, this will align the elements in the vertical order. Here we have an example with two Text widget with some values in vertical order.

@Composable
fun FlowerCard(flower: Flowers){
Column {
Text(
text = flower.name,
style = TextStyle(
color = gray,
fontSize = 16.sp
)
)
Text(
text = flower.price,
style = TextStyle(
color = colorPrimary,
fontSize = 16.sp
)
)
}
}

Now, let’s take add item button to Right of flower info.

As you might expect, you can use the Row() function which lets you stack elements horizontally. The default settings stack all the children directly next to each other, with no spacing.

@Composable
fun FlowerCard(flower: Flowers){
Row(modifier = Modifier.padding(20.dp)) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = flower.name,
style = TextStyle(
color = gray,
fontSize = 16.sp
)
)
Text(
text = flower.price,
style = TextStyle(
color = colorPrimary,
fontSize = 16.sp
)
)
}
IconButton(
onClick = { },
modifier = Modifier.background(
color = colorPrimary,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(Icons.Default.Add, tint = Color.White)
}
}
}

With the code above, we used modifier to add some padding. But, what exactly is a modifier? A modifier is an ordered, immutable collection of elements that decorate or add behavior to Compose UI elements like backgrounds, padding, click event listeners, and many more.

Now, let’s wrap this row with a Card.

@Composable
private fun FlowerCard(flower: Flowers) {
Card(
shape = RoundedCornerShape(14.dp),
backgroundColor = Color.White,
modifier = Modifier.padding(10.dp).width(180.dp)
) {
Row(modifier = Modifier.padding(20.dp)) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = flower.name,
style = TextStyle(
color = gray,
fontSize = 16.sp
)
)
Text(
text = flower.price,
style = TextStyle(
color = colorPrimary,
fontSize = 16.sp
)
)
}
IconButton(
onClick = { },
modifier = Modifier.background(
color = colorPrimary,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(Icons.Default.Add, tint = Color.White)
}
}
}
}

Card has a lot of attributes that you can use. To have a rounded shape (or any other shape), you can use the shape attribute. Using modifier you can give padding, width and height for the card. Card will accept one child under it to show information.

Your card will look like this.
Your card will look like this.
Your Card will look like this.

Now, want to add Image of flower above the flower information. Mean, you want to show multiple information on the card, but as we know, Card accepts only one child. Thus you have to use the Column.

@Composable
private fun FlowerCard(flower: Flowers) {
Card(
shape = RoundedCornerShape(14.dp),
backgroundColor = Color.White,
modifier = Modifier.padding(10.dp).width(180.dp)
) {
Column(
modifier = Modifier.fillMaxWidth().padding(10.dp),
) {
Image(
modifier = Modifier.size(140.dp),
asset = imageResource(id = flower.image)
)
Row(modifier = Modifier.padding(top = 20.dp)) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = flower.name,
style = TextStyle(
color = gray,
fontSize = 16.sp
)
)
Text(
text = flower.price,
style = TextStyle(
color = colorPrimary,
fontSize = 16.sp
)
)
}
IconButton(
onClick = { },
modifier = Modifier.background(
color = colorPrimary,
shape = RoundedCornerShape(10.dp)
)
) {
Icon(Icons.Default.Add, tint = Color.White)
}
}
}
}
}

In the above code, to add an image we used the Composable function Image.

The asset property is used to provide an image resource. imageResource function will accept the ID of the image and provide the ImageAsset for the view. Image also has a lot more properties for scaling, aligning, and changing the UI representation of the image.

Creating a List of flowers.

Normally, to make a list you’d use something like a RecyclerView. Similar to it, a LazyRowFor is used in Jetpack Compose. It is a horizontal scrolling list that only composes and lays out the currently visible items.

Now putting all together, creating PopularFlowersList().

@Composable
private fun PopularFlowersList() {
LazyRowFor(
items = FlowersData.list,
modifier = Modifier.fillMaxWidth()
) { flowers ->
FlowerCard(flowers)
}
}

Congratulations!!! You’ve built your first real world UI using Jetpack Compose.

Note: Since compose is still in alpha, widgets or its attributes are subject to change.

Here is the link for the example:
https://github.com/Mindinventory/Flower-App-Jetpack-Compose

This is just the beginning of this series. In the next installment, we are in plan to create a sample with MVVM design pattern, so stay tune for that and by the time keep composing!!

Mindful Engineering

Mindinventory Tech Blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store