Blog Infos
Author
Published
Topics
Published

Jetpack Compose is a modern UI toolkit that is designed to simplify UI development in Android.

This is the second part of the 2 part series on Jetpack Compose Basics.

  1. Jetpack Compose Basics — Part 1
  2. Jetpack Compose Basics — Part 2 (Design Code Samples)

In the first part, we tried to address some questions that come up with Compose. We understood what are the basic functions in Compose and the rules and annotations used for them. In this blog, we will try to use them and design some simple UI using Jetpack Compose.

Let’s refer to the designs used in the Google Developer’s Course on Compose Unit 1 — Pathway 3 and try to compose them.

Design 1: Birthday Greeting Card

 

In the first design, we will draw a birthday greeting card like the above. For the “message” and “from” strings, we will use Text Composable. Let’s make a Composable function BirthdayGreetingWithText() and pass two parameters, one for the “message” and one for the “from” text. To align it in a vertical arrangement, we use the Column function.

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Column {
Text(text = message)
Text(text = from)
}
}

To specify the text size of the text, Text Composable takes a parameter — fontSize. We can specify the text size with sp extension available in TextUnit Class. We can also set the text color by specifying it in the color param in Text Composable. There is a modifier param as well which allows us to specify the alignment, padding, width, height, etc.

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Column {
Text(
text = message,
fontSize = 24.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
.padding(10.dp)
)
Text(
text = from,
fontSize = 20.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
.padding(10.dp)
)
}
}

To add background color, we can add this column inside a Surface and give color to that, let’s try that.

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Surface(color = Color.Magenta) {
Column {
Text(
text = message,
fontSize = 24.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
.padding(10.dp)
)
Text(
text = from,
fontSize = 20.sp,
color = Color.White,
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
.padding(10.dp)
)
}
}
}

How do we preview this?

To preview this, we have to create a composable function with @Preview annotation to be able to see the UI in the Design tab.

@Preview(showBackground = true)
@Composable
fun BirthdayGreetingWithTextPreview() {
ComposeExampleTheme {
BirthdayGreetingWithText("Happy Birthday Alankrita!", "From, Alankrita")
}
}

Build and refresh and you will get to see something like this in the Design preview. It is a surface with a Magenta color with two Text Composable in vertical arrangement aligned in the center horizontal in white color and some padding with some fontSize.

 

To add an image to the greeting card, let’s use Image Composable. painterResource Composable uses the parameter id of the drawable and returns painter which can be used in Image Composable. Feel free to choose any drawable image that feels attractive in your greeting card.

Let’s make another Composable function BirthdayGreetingWithImage() with 3 params — message, from, and image. Let’s use a Box layout for this. The box layout is used to stack elements on top of one another. Box layout also lets you configure the specific alignment of the elements that it contains.

@Composable
fun BirthdayGreetingWithImage(message: String, from: String, image: Int) {
val image = painterResource(id = image)
Box {
Image(
painter = image,
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
contentScale = ContentScale.Crop
)
BirthdayGreetingWithText(message, from)
}
}

Let’s preview the greeting card with image and text.

@Preview(showBackground = true)
@Composable
fun BirthdayGreetingWithImagePreview() {
ComposeExampleTheme {
BirthdayGreetingWithImage("Happy Birthday Alankrita!", "From, Alankrita", R.drawable.ic_launcher_background)
}
}

Yay! The birthday greeting card is ready. Let’s check out another design example.

Design 2: Compose Article

 

 

In this design, let’s create a Compose article UI. This contains an image with full-screen width. It has 3 text elements with some font size and padding. The second and third text elements are in Justify text alignment. Note that all the elements are placed in vertical order. So, we can use Column Composable to arrange the elements. Let’s write a Composable function — ComposeArticle() that accepts one image and 3 text values.

@Composable
fun ComposeArticle(head: String, body1: String, body2: String, image: Int) {
val image = painterResource(id = image)
Column(modifier = Modifier.fillMaxSize()) {
Image(
painter = image,
contentDescription = "Jetpack Compose Article",
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentScale = ContentScale.Crop
)
Text(
text = head,
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 8.dp)
)
Text(
text = body1,
textAlign = TextAlign.Justify,
modifier = Modifier.padding(16.dp, 8.dp, 16.dp, 8.dp)
)
Text(
text = body2,
textAlign = TextAlign.Justify,
modifier = Modifier.padding(16.dp, 8.dp, 16.dp, 16.dp)
)
}
}

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

,

Jetpack Compose: Drawing without pain and recomposition

This is a talk on recomposition in Jetpack Compose and the myths of too many calls it is followed by. I’ll briefly explain the reasons behind recompositions and why they are not as problematic as…
Watch Video

Jetpack Compose: Drawing without pain and recomposition

Vitalii Markus
Android Engineer
Flo Health Inc.

Jetpack Compose: Drawing without pain and recomposition

Vitalii Markus
Android Engineer
Flo Health Inc.

Jetpack Compose: Drawing without pain and recomposition

Vitalii Markus
Android Engineer
Flo Health Inc.

Jobs

To align text in Justify, we can set the textAlign param in Text Composable as TextAlign.Justify. To preview this, let’s add another function — ComposeArticlePreview()

@Preview(showBackground = true)
@Composable
fun ComposeArticlePreview() {
ComposeExampleTheme {
ComposeArticle(
"Jetpack Compose tutorial",
"Jetpack Compose is a modern toolkit for building native Android UI. Compose simplifies and accelerates UI development on Android with less code, powerful tools, and intuitive Kotlin APIs.",
"In this tutorial, you build a simple UI component with declarative functions. You call Compose functions to say what elements you want and the Compose compiler does the rest. Compose is built around Composable functions. These functions let you define your app\\'s UI programmatically because they let you describe how it should look and provide data dependencies, rather than focus on the process of the UI\\'s construction, such as initializing an element and then attaching it to a parent. To create a Composable function, you add the @Composable annotation to the function name.",
R.drawable.ic_launcher_background)
}
}

Build and refresh to see the changes. The Compose Article design is ready.

Design 3: Task Manager

 

 

In this design, we will create a design that looks like a task manager, which shows the UI like above when all your tasks are done. It has an image and 2 text elements. All the items are center-aligned horizontally and vertically. Let’s write a Composable function — TaskManager() for this.

@Composable
fun TaskManager(head: String, body: String) {
val image = painterResource(id = R.drawable.ic_launcher_background)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = image,
contentDescription = "All tasks done",
modifier = Modifier
.width(150.dp)
.height(150.dp)
)
Text(
text = head,
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(0.dp, 24.dp, 0.dp, 8.dp)
)
Text(
text = body,
fontSize = 16.sp
)
}
}
view raw TaskManager1.kt hosted with ❤ by GitHub

To set the elements in the vertical center, we have assigned the value Arrangement.Center to verticalArrangement param in Column Composable. And to set elements in the horizontal center, we have used Alignment.CenterHorizontally in horizontalAlignment param in Column Composable. Let’s preview this by writing another Preview Composable function — TaskManagerPreview()

@Preview(showBackground = true)
@Composable
fun TaskManagerPreview() {
ComposeExampleTheme {
TaskManager(
"All tasks completed",
"Nice work!"
)
}
}
view raw TaskManager2.kt hosted with ❤ by GitHub

The task manager design is ready.

Design 4: Compose Quadrant

 

 

In this design, the screen is divided into 4 quadrants. Each Quadrant has 2 text elements in the center of that quadrant. All quadrants have different colors.

Let’s first draw what one card (quadrant) looks like. Each card has 2 text elements. The second text uses Justify as text alignment. The first one is bold. And both text combined is placed in the center horizontally and vertically.

@Composable
fun ComposeQuadrant(color: Color, head: String, body: String, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.background(color)
.padding(16.dp)
.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = head,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(0.dp, 0.dp, 0.dp, 16.dp)
)
Text(
text = body,
textAlign = TextAlign.Justify,
)
}
}

If we preview this, this will show one quadrant preview.

@Preview(showBackground = true)
@Composable
fun ComposeQuadrantPreview() {
ComposeExampleTheme {
ComposeQuadrant(
color = Color.Cyan,
head = "Row composable",
body = "A layout composable that places its children in a horizontal sequence.",
)
}
}

 

Now, we have to show 4 quadrants. For this, we can use 2 rows in a column. To assign each composable quadrant equal width, set the modifier weight as 1f in each card composable. And to set each quadrant of equal height, set modifier weight as 1f in each row in the column. Let’s look into the code.

@Composable
fun ComposeQuadrants() {
Column(modifier = Modifier.fillMaxSize()) {
Row(Modifier.weight(1F)) {
ComposeQuadrant(
color = Color.Green,
head = "Text composable",
body = "Displays text and follows Material Design guidelines.",
modifier = Modifier.weight(1f)
)
ComposeQuadrant(
color = Color.Yellow,
head = "Image composable",
body = "Creates a composable that lays out and draws a given Painter class object.",
modifier = Modifier.weight(1f)
)
}
Row(Modifier.weight(1F)) {
ComposeQuadrant(
color = Color.Cyan,
head = "Row composable",
body = "A layout composable that places its children in a horizontal sequence.",
modifier = Modifier.weight(1f)
)
ComposeQuadrant(
color = Color.LightGray,
head = "Column composable",
body = "A layout composable that places its children in a vertical sequence.",
modifier = Modifier.weight(1f)
)
}
}
}

Let’s preview this.

@Preview(showBackground = true)
@Composable
fun ComposeQuadrantPreview() {
ComposeExampleTheme {
ComposeQuadrants()
}
}

Yay! The ComposeQuadrants Composable is ready.

Design 5: Business Card

 

 

In this design, we will create a business card Composable. There are two sections in it. One is the top layer in which we have an image and two text elements. It is placed in the center horizontally. Let’s create a Composable for the top portion — BusinessCardTop()

@Composable
fun BusinessCardTop() {
val image = painterResource(id = R.drawable.ic_launcher_background)
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom
) {
Image(
painter = image,
contentDescription = "All tasks done",
modifier = Modifier
.width(150.dp)
.height(150.dp)
)
Text(
text = "Alankrita",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(0.dp, 24.dp, 0.dp, 8.dp)
)
Text(
text = "Hi From Alankrita",
fontSize = 16.sp
)
}
}

Let’s preview this and see how does it look like,

@Preview(showBackground = true)
@Composable
fun BusinessCardPreview() {
ComposeExampleTheme {
BusinessCardTop()
}
}

 

Great! Now, let’s look at the bottom section. The bottom section has 3 rows arranged in a column. Each row has an image and a text. Let’s also add some padding to them to make them look nice.

@Composable
fun BusinessCardBottomRow(contact: String) {
val image = painterResource(id = R.drawable.ic_launcher_background)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(30.dp, 2.dp, 20.dp, 2.dp)
) {
Image(
painter = image,
contentDescription = contact,
modifier = Modifier
.width(30.dp)
.height(30.dp)
.padding(5.dp)
.wrapContentWidth(Alignment.Start)
)
Text(
contact,
modifier = Modifier
.padding(10.dp, 0.dp, 10.dp, 0.dp)
.align(Alignment.CenterVertically)
.fillMaxWidth()
.wrapContentWidth(Alignment.End)
)
}
}

Let’s preview this and see how does it look like.

@Preview(showBackground = true)
@Composable
fun BusinessCardPreview() {
ComposeExampleTheme {
BusinessCardBottomRow()
}
}

 

Awesome! The row item is ready. Let’s add 3 rows in a column. Add your different contact details here.

@Composable
fun BusinessCardBottom() {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(0.dp, 0.dp, 0.dp, 50.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom
) {
BusinessCardBottomRow("contact@gmail.com")
BusinessCardBottomRow("contact@gmail.com")
BusinessCardBottomRow("contact@gmail.com")
}
}

Let’s preview this.

@Preview(showBackground = true)
@Composable
fun BusinessCardPreview() {
ComposeExampleTheme {
BusinessCardBottom()
}
}

 

Going well so far. We have the top section ready and we have the bottom section ready. Now, let’s make some changes and add some weight to the UI.

//Business Card
@Composable
fun BusinessCard() {
Column(modifier = Modifier.fillMaxSize()) {
BusinessCardTop(modifier = Modifier.weight(3F))
BusinessCardBottom(modifier = Modifier.weight(2F))
}
}
@Composable
fun BusinessCardTop(modifier: Modifier) {
val image = painterResource(id = R.drawable.ic_launcher_background)
Column(
modifier = modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom
) {
Image(
painter = image,
contentDescription = "All tasks done",
modifier = Modifier
.width(150.dp)
.height(150.dp)
)
Text(
text = "Alankrita",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(0.dp, 24.dp, 0.dp, 8.dp)
)
Text(
text = "Hi From Alankrita",
fontSize = 16.sp
)
}
}
@Composable
fun BusinessCardBottom(modifier: Modifier) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(0.dp, 0.dp, 0.dp, 50.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom
) {
BusinessCardBottomRow("contact@gmail.com")
BusinessCardBottomRow("contact@gmail.com")
BusinessCardBottomRow("contact@gmail.com")
}
}
@Composable
fun BusinessCardBottomRow(contact: String) {
val image = painterResource(id = R.drawable.ic_launcher_background)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(30.dp, 2.dp, 20.dp, 2.dp)
) {
Image(
painter = image,
contentDescription = contact,
modifier = Modifier
.width(30.dp)
.height(30.dp)
.padding(5.dp)
.wrapContentWidth(Alignment.Start)
)
Text(
contact,
modifier = Modifier
.padding(10.dp, 0.dp, 10.dp, 0.dp)
.align(Alignment.CenterVertically)
.fillMaxWidth()
.wrapContentWidth(Alignment.End)
)
}
}
@Preview(showBackground = true)
@Composable
fun BusinessCardPreview() {
ComposeExampleTheme {
BusinessCard()
}
}

The business card is ready. Congratulations!

With the 5 designs we created in this blog, we have learned about three layouts — Row, Column, and Box. We have also learned about Modifier.weight. We also came across the functionality of verticalArrangement and horizontalAlignment. We learned to add an Image and Text Composable with fontWeight, fontSize, textAlign, and modifier. Here is the Github link with all the designs code that we have implemented in this blog. Feel free to refer to it.

References

Hope you find this blog helpful in getting started with the Jetpack Compose. If you like this, don’t forget to hit the 👏 .

This article was originally published on proandroiddev.com on October 27, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE
Menu