Happy Employees == Happy ClientsCAREERS AT DEPT®
DEPT® Engineering BlogPlatforms

Flexible UI components made easy with Jetpack Compose

Learn how to create reusable UI components with Google's new modern UI toolkit for Android.

Unlike the traditional XML layouts, Compose makes it easy to create UI components that are easily scalable, reusable, and provide a consistent experience for your application's users.

When creating the UI components, remember to follow these rules:

  1. Avoid hardcoding any text, states, or values
  2. Keep the size of the container scalable
  3. Do not hold any logic in your UI
  4. Keep it well documented, and add previews to show different ways of usage

Let's dive into it and see some examples of how we can take the Compose approach to create the following layouts:

Identify similarities

Although they might look different at first glance, we can identify the following similarities:

  1. Both are contained in a scalable box with rounded corners
  2. Both have a box outline of equal width

Secondly, they have the following properties, which can be customized with parameters. These include:

  1. The outline color
  2. The box background color

Creating a reusable component

Using this information, we can setup a scalable box like this:

@Composable
fun ScalableBox(
    boxColor: Color = Color.White,
    outlineColor: Color = Color.Unspecified,
    boxOnClick: () -> Unit = {},
    modifier: Modifier,
    content: @Composable () -> Unit = {},
) {
    Box(
        modifier = modifier
            .clip(RoundedCornerShape(12.dp))
            .background(boxColor)
            .border(
                width = 2.dp,
                color = outlineColor,
                shape = RoundedCornerShape(12.dp)
            )
            .clickable { boxOnClick }
            .padding(16.dp)
    ) {
        content()
    }
}

This Composable has some fixed properties such as padding, rounded corner radius, and outline width. Further, it has some customizable properties such as box color, outline color, and the content that will be contained inside the box. These are all passed as parameters.

Now, we can enclose our main UI elements in this Scalable Box, passing it the properties we need accordingly.

The code for the yellow-bordered, gray background box:

@Composable
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, widthDp = 300, heightDp = 200)
fun ParagraphFieldPreview() {
    Column(Modifier.padding(16.dp)) {
        ScalableBox(
            boxColor = Color.DarkGray,
            outlineColor = Color.Yellow,
            modifier = Modifier
        ) {
            Text(
                text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " +
                        "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, " +
                        "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
                color = Color.White
            )
        }
    }
}

And the code for the black bordered, white background box:

@Composable
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF, widthDp = 300, heightDp = 200)
fun ImageAndTextFieldPreview() {
    Column(Modifier.padding(16.dp)) {
        ScalableBox(
            boxColor = Color.White,
            outlineColor = Color.Black,
            modifier = Modifier
        ) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Image(
                    painter = painterResource(id = R.drawable.ic_launcher_foreground),
                    contentDescription = null,
                    modifier = Modifier.size(60.dp),
                    colorFilter = ColorFilter.tint(Color.Black.copy(alpha = 0.8f))
                )
                Text(text = "Lorem ipsum dolor")
            }
        }
    }
}

Both Composable uses ScalableBox to configure their container properties and create the enclosed UI.

And just like that, you have created your first flexible UI components with Jetpack Compose!

Wrapping up

That all sounds great, but what if your requirements need you to create a color-changing spiral box? You can still use the same scalable box component!

Check out the full source code below to find out how:
https://github.com/deptagency/JetpackComposeExample

Cheers!