Jetpack Compose

Jetpack Compose: Part 1 — Design

Better design with less lines of code.

Himanshu Choudhary
Aug 3, 2020 · 5 min read

Hello everyone, there’s been a lot going on in the android community, a lot of changes are coming up and one of them is Jetpack Compose.

This blog is the first part of the Jetpack Compose series. After completing this, you can also check out how to make a more complex UI with multiple lists of data in the second part of this series.

Those who know what Jetpack Compose is can skip this part.

Introduction

Jetpack Compose simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs. — Android Developers

Or you can understand it by the following points :

A new to develop Android Apps UI:

  1. Less Code: No more Recycler view Adapters and XML files.
  2. Intuitive: As app state changes, your UI automatically updates.
  3. Faster App development: Lesser lines of code, live preview, UI and functionality in a single function.
  4. Powerful: In built support for most of the things like (Material design, dark theme, animations and more). No external library needed.

Should I use it now ?

Right now, it is in development which means a lot of changes will occur before it will be in the production. So, to answer your question I will say that if you are an enthusiast and want to learn something which can benefit you in the near future then you should definitely start using it for your own projects.

Where do I start ?

  • Start with the simple design.
  • Move to the complex UI.
  • Integrate functionality to it.

Dependencies

These configuration are for compose version : 0.1.0-dev13

  • Download Android Studio in which compose is available. Right now, it is available in Canary version.
android {
...

buildFeatures {
compose true
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
composeOptions {
kotlinCompilerExtensionVersion "0.1.0-dev13"
}
}
dependencies {... implementation 'androidx.ui:ui-core:0.1.0-dev13'
implementation 'androidx.ui:ui-tooling:0.1.0-dev13'
implementation 'androidx.ui:ui-layout:0.1.0-dev13'
implementation 'androidx.ui:ui-material:0.1.0-dev13'
}

In this blog, we will design a simple UI which will cover the use of different components available in the Jetpack Compose.

What we are going to build ?

Final product

We will build this UI in two parts:

  • Header: It includes heading and sub heading at the top and one image on the top left.
  • Body: It includes all the six blocks.

Before starting to code, import all the icons which you will need in the design from here.

Header

@Composable
fun header() {
Row(horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
verticalGravity = Alignment.CenterVertically) {
Column {
Text(text = "Developer's App", color = Color.Black, fontSize = TextUnit.Sp(29),
fontFamily = FontFamily.SansSerif,
style = TextStyle(fontWeight = FontWeight.Bold),
modifier = Modifier.padding(top = 30.dp, start = 40.dp))
Row {
Text(text = "Home", color = Color.Gray, fontSize = TextUnit.Sp(13),
fontFamily = FontFamily.SansSerif,
modifier = Modifier.padding(start = 40.dp, top = 3.dp))
Image(vectorResource(id = R.drawable.down))
}
}
Image(imageResource(id = R.drawable.message),
modifier = Modifier.padding(end = 40.dp).width(35.dp).height(35.dp))
}
}

Here 4 components of Jetpack compose are used:

  1. Text a.k.a TextView
  2. Column a.k.a Vertical LinearLayout
  3. Row a.k.a Horizontal LinearLayout
  4. Image a.k.a ImageView

Inside the column of these components are their properties which you can get by their names.

fillMaxWidth() -> match_parent

Some important things which you need to keep in mind :

  1. If you are using a drawable image which is in .xml format. Then, you will have to use vectorResource. Otherwise, you can use imageResource for any other format.
  2. Arrangement in Row is space between its component. If I am using Arrangement.SpaceBetween it means that both the component will aligned at their respective side ends and space will be in between. There are two more types of Arrangement which I will not tell. Do your hands dirty in them😁
  3. Properties like padding, width, height, etc. are available in Modifier.

Important Note:

Every function that you will access with the Modifier instance returns the instance of modifier only. So with this you can call multiple functions in the same line.

For example :

Modifier.fillMaxHeight().fillMaxWidth()
.gravity(Alignment.CenterHorizontally).padding(top = 15.dp)

Body

First, we will have to design the item layout and that layout will be resused in all the six blocks.

@Composable
fun itemLayout(title: String, subTitle: String, description: String, image: Int) {

Box(backgroundColor = Color(red = 230, green = 230, blue = 250),
modifier = Modifier
.clip(shape = RoundedCornerShape(8.dp))
.width(150.dp).height(180.dp)) {

ConstraintLayout(modifier = Modifier.fillMaxHeight().fillMaxWidth()
.gravity(Alignment.CenterHorizontally).padding(top = 15.dp),
constraintSet = ConstraintSet {
val imageComponent = tag("image")
val titleComponent = tag("title")
val subTitleComponent = tag("subTitle")
val descriptionComponent = tag("description")

imageComponent.apply {
top constrainTo parent.top
left constrainTo parent.left
right constrainTo parent.right
}

titleComponent.apply {
top constrainTo imageComponent.bottom
left constrainTo parent.left
right constrainTo parent.right
}

subTitleComponent.apply {
top constrainTo titleComponent.bottom
left constrainTo parent.left
right constrainTo parent.right
}

descriptionComponent.apply {
bottom constrainTo parent.bottom
left constrainTo parent.left
right constrainTo parent.right
top constrainTo subTitleComponent.bottom
}

}
) {
val typography = MaterialTheme.typography
Image(imageResource(id = image),
modifier = Modifier.tag("image").padding(top = 15.dp))
Text(text = title,
style = typography.body1,
modifier = Modifier.tag("title").padding(top = 5.dp))
Text(text = subTitle,
color = Color.Gray,
fontSize = TextUnit.Sp(11),
modifier = Modifier.tag("subTitle").padding(top = 3.dp))
Text(text = description,
color = Color.Blue,
fontSize = TextUnit.Sp(11),
modifier = Modifier.tag("description").padding(top = 16.dp))
}
}
}

Before understanding it, copy and paste it in your file, have a preview of it. Change some properties and understand their result.

New components :

  1. Box — something like CardView.
  2. ConstraintLayout is same.
  3. ConstraintSet is same.
  4. Modifier.tag is the id of the component.

What are we are doing in the above code ?

  1. There is a box with round corners, a colored background and particular width and height.
  2. In that, there is a constraint layout, which have two parts. On for the constraint set where constraints are defined and another is the body where components are defined.
  3. In the constraint set, first we are getting the component by their tag and then setting their constraints with respect to other.
  4. With typography, we define the style the text : How it will look?
@Composable
fun rowWithTwoItem(tabs: List<TabModel>) {
Row(modifier = Modifier.padding(top = 20.dp).fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly) {
itemLayout(title = tabs[0].title, subTitle = tabs[0].subTitle,
description = tabs[0].description, image = tabs[0].image)
itemLayout(title = tabs[1].title, subTitle = tabs[1].subTitle,
description = tabs[1].description, image = tabs[1].image)
}
}

@Composable
fun columnOfThree() {
val tabList = AdapterData.getTabsData()
Column {
rowWithTwoItem(listOf(tabList[0], tabList[1]))
rowWithTwoItem(listOf(tabList[2], tabList[3]))
rowWithTwoItem(listOf(tabList[4], tabList[5]))
}
}
@Preview
@Composable
fun main() {
VerticalScroller {
header()
columnOfThree()
}

}

In this code :

First, we are making a row of two items.

Then a column of these three rows

Which leads to completion of our UI.

We are passing data with the use of a model.

data class TabModel (
val title:String = "",
val subTitle:String = "",
val description:String = "",
val image:Int = 0
)

In this article we learned about the various components of Jetpack Compose and made a simple design by using them.

I hope this article would have helped you. If you have any suggestions, queries or anything, write it in the comment section.

Happy Coding!