Exploring Jetpack Compose: Stack

E

If you’re enjoying my posts on Jetpack Compose, check out some details on the book I’ll be writing on Compose!

When it comes to laying out groups of components in our screens, it’s not always the case that we want them to be sequentially displayed in a vertical or horizontal manner. There may be times in which we want to have some items drawn behind and/or on top of others. When this is the case, the Stack composable provides the functionality for us to achieve this. The stack itself has a single constructor that can be used to compose an instance of a Stack:

@Composable
fun Stack(
    modifier: Modifier = Modifier,
    children: @Composable() StackScope.() -> Unit
)

The stack has two properties that can be provided into its constructor:

  • modifier – the modifier to be applied to the button. If not provided, none will be applied
  • children – the Composable to be used for the content of the Stack

Let’s begin by building a Stack component that displays four child components, each aligned to a different part of the container:

Stack(modifier = Modifier.fillMaxSize()) {
    Text(
        text = ("Top!"),
        modifier = Modifier.gravity(Alignment.TopCenter).padding(16.dp)
    )

    Text(
        text = ("Left!"),
        modifier = Modifier.gravity(Alignment.CenterStart).padding(16.dp)
    )

    Text(
        text = ("Right!"),
        modifier = Modifier.gravity(Alignment.CenterEnd).padding(16.dp)
    )

    Text(
        text = ("Bottom!"),
        modifier = Modifier.gravity(Alignment.BottomCenter).padding(16.dp)
    )
}

As we can see here, each of our Text components has been aligned to a separate part of the screen. If we did not provide any modifiers for the gravity of these children, then they would all be placed in at the top/start of the container by default. Gravity is not explicit either, so two children could have the same gravity and end up overlapping, or having different gravity but overlapping due to the size of the content. The core concept for the Stack is the gravity of the child components – this allows us to depict where in the container our child components should be aligned to.

When it comes to the layout of these child components, it’s important to think about the z-index for them. The z-index is applied based on the order in which the child components are declared in. So for example, if there was any overlapping here, then the ‘Bottom’ text would be drawn on top of the other children because it is the last component defined in our stack.

Whilst the example above doesn’t demonstrate a good use-case for the index, in some case we may want specific components to be drawn underneath others  – for example, having something displayed underneath our text child components as a background, purposefully overlapping them over the top of this content:

Stack(modifier = Modifier.fillMaxSize()) {
    Box(
        backgroundColor = Color.LightGray,
        modifier = Modifier.matchParentSize()
    )

    Text(
        text = ("Top!"),
        modifier = Modifier.gravity(Alignment.TopCenter).padding(16.dp)
    )

    Text(
        text = ("Left!"),
        modifier = Modifier.gravity(Alignment.CenterStart).padding(16.dp)
    )

    Text(
        text = ("Right!"),
        modifier = Modifier.gravity(Alignment.CenterEnd).padding(16.dp)
    )

    Text(
        text = ("Bottom!"),
        modifier = Modifier.gravity(Alignment.BottomCenter).padding(16.dp)
    )
}

As we can see above, our Text components are all draw on top of the component which has been declared as the first item in our Stack. With this being given the z-index of 0, the child components after it are assigned a z-index based on their defined order, meaning that they are drawn on top of the Box component.

In this post we’ve taken a quick dive into the Stack component from Jetpack Compose. Stay tuned for the next post and in the meantime, subscribe to updates on my Jetpack Compose book 🙂

About the author

hitherejoe

Add Comment

By hitherejoe