Jetpack Compose: Getting Started

Aug 1 2023 · Kotlin 1.8.10, Android 13, Android Studio Flamingo

Part 1: Make a Simple Interface

04. Leverage Modifiers

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 03. Building a Simple Layout Next episode: 05. Use a Button

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 04. Leverage Modifiers

Rendering items on the screen is only one part of building user interfaces. You also need to be able to customize the appearance and behavior of the items that you render on the screen. So far, we have discussed how to create and render items on the screen, we will dive deeper into how to customize the appearance and behavior of the items that you want to render on the screen.

Jetpack Compose provides us with the Modifier class that we can use to customize the look and feel of our Composables. All in-built Composables have a modifier parameter that you can use in order to customize the appearance and behavior of the Composable.

You can also proivde a modifier to a Composable function that you create. This allows you to customize the appearance and behavior of the Composable function that you create and would like to re-use in different scenarios and contexts.

Modifiers are standard Kotlin objects. You can create a Modifier by invoking one of the Modifier class functions. Modifiers allow for multiple invocations, which means that you can apply multiple modifiers to a single Composable. This is done by chaining the modifier functions together.

Modifiers allow you do the following:

  • Change the composable’s size, layout, behavior, and appearance
  • Add information, like accessibility labels
  • Process user input
  • Add high-level interactions, like making an element clickable, scrollable, draggable, or zoomable

Modifier Class

Let us add some modifications to our ProfileBar Composable.

We will begin by wrapping the Text Composable that has the Hello, Kodeco text in a Column Composable. This will allow us to add multiple Composables to the Column Composable.

@Composable
fun ProfileBar(){

    Row(modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ){

        Image(
            modifier = Modifier.size(50.dp),
            painter = painterResource(id = R.drawable.ic_profile),
            contentDescription = null,
        )

        Column(
            verticalArrangement = Arrangement.SpaceBetween,
        ){

            Text(
                text = "Hello, Kodeco",
                style = MaterialTheme.typography.bodyLarge,
            )

        }

        Image(
            modifier = Modifier.size(50.dp),
            painter = painterResource(id = R.drawable.ic_notifications),
            contentDescription = null,
        )

    }

}

Next, we shall add some modifications to this Column. We will provide a width, height and padding to the Column.


Column(
    verticalArrangement = Arrangement.SpaceBetween,
    modifier = Modifier
        .width(200.dp)
        .height(100.dp)
        .padding(16.dp)
){

    Text(
        text = "Hello, Kodeco",
        style = MaterialTheme.typography.bodyLarge,
    )


}

With our Modifications, the ProfileBar Composable now looks like this:

Error: This image is missing a width attribute

Please provide one in the form of ![width=50%](./images/04-profile-bar-modifications.png)

The image has been hidden until this issue is resolved.

Order of Modifiers

As you continue to chain Modifiers, you will continue noticing the behavior might look different from what you expect. This is because the order in which you chain the modifiers matters. The order in which you chain the modifiers determines the order in which the modifiers are applied to the Composable.

Consider the following two scenarios:

  • Scenario 1
Box(modifier = Modifier
          .size(50.dp)
          .background(color = Color.Red)
          .clip(CircleShape))

This will result in a red square of sides 50dp. This may seem strange, however, since we have painted our UI with the color red and then clipped it to a circle shape, the result is a red square of sides 50dp since the paint was already applied before the clipping.

  • Scenario 2

Box(modifier = Modifier
          .size(50.dp)
          .clip(CircleShape)
          .background(color = Color.Red))

This will result in a red circle of radius 25dp. This is because we have clipped the UI to a circle shape and then painted it with the color red. Since the clipping was already applied, the result is a red circle of radius 25dp.

Jetpack Compose offers some scope to a given set of Modifiers. This means that some modifiers can only be applied to certain Composables. For example, the matchParentSize modifier can only be applied to Composables that are children of the BoxScope.

@Composable
fun HelloBox(){

    Box(modifier = Modifier
          .padding(10.dp)
          .size(200.dp)
          .border(width = 2.dp, color = Color.Blue)){

          Text(
              text = "Hello World",
              modifier = Modifier
                  .padding(10.dp)
                  .matchParentSize())

      }

}

The matchParentSize modifier can only be applied to the Text Composable because it is a child of the BoxScope. If you try to apply the matchParentSize modifier to the Box Composable, you will get a compiler error.

@Composable
fun HelloBox(){

    Box(modifier = Modifier
          .padding(10.dp)
          .size(200.dp)
          .border(width = 2.dp, color = Color.Blue)
          .matchParentSize()){

          Text(
              text = "Hello World",
              modifier = Modifier.padding(10.dp))

      }

}

We have had a look at how to use Modifiers to customize the appearance and behavior of our Composables. We have also had a look at the order in which we chain Modifiers and how that affects the appearance and behavior of our Composables. We have also had a look at the scope of Modifiers and how that affects the Composables that we can apply a given Modifier to.

In our next episode, we will have a look at how to use Buttons and how to handle click events in Jetpack Compose.