Exploring Jetpack Compose: Row & Column

E

Within Android Studio 4.0 Canary 1 we can start exploring Jetpack compose, a new way to build the UI for your android applications in a declarative manner. To get started with jetpack compose, there is a great tutorial on the official developer site. In this series of articles I want to dive into each of the components that are available, exploring how we can utilise each of them within our applications.


When it comes to laying out views in Android, we have access to components such as the Linear Layout, Constraint Layout, Relative layout etc to contain our child views and position them in the required format. The Linear Layout is often used to create vertical / horizontal layouts of views, providing a simple option of setting an orientation to control the direction in which the children are laid out. When it comes to Jetpack Compose, it is likely we will want to lay out child components in this vertical / horizontal format. In these case we have access to a couple components which will help us to do so.


To lay out child components in a vertical or horizontal format we can utilise the Row or Column component. These components are very similar in both their declaration and under the hood, so we’re going to look at both of them together.

When wanting to display a collection of child components in a vertically stacked manner we can use the Column. If we dive into the source code for the Column then we can see the below function declaration for creating a new instance:

@Composable
fun Column(
    modifier: Modifier = Modifier.None,
    arrangement: Arrangement = Arrangement.Begin,
    children: @Composable() ColumnScope.() -> Unit
)

On the other hand we also have the Row component – this is used when we wish to display a collection of child components in a horizontally arranged sequence. If we dive into the source code for the Row then we can see the below function declaration for creating a new instance:

@Composable
fun Row(
    modifier: Modifier = Modifier.None,
    arrangement: Arrangement = Arrangement.Begin,
    children: @Composable() RowScope.() -> Unit
)

From these two snippets of code we can already see some similarities. The first argument, the modifier, is used to apply decorations to the way in which our component is laid out. We covered these modifiers in this previous article.

We also have the arrangement argument, which is used to declare how the child components should be arranged within the main axis of the component (which is either horizontal or vertical). The Arrangement can be set to one of six different values.

Arrangement.Begin (default value) – Place child components as close to the start of the main axis

Arrangement.End – Place child components as close to the end of the main axis

Arrangement.Center – Place child components as close to the center of the main axis

Arrangement.SpaceEvenly – Place child components so that they are evenly spaced across the main axis, including any free space both before the first child component and after the last child component

Arrangement.SpaceAround – Place child components so that they are evenly spaced across the main axis, including any free space both before the first child component and after the last child component, with only half the amount of space present between each child component

Arrangement.SpaceBetween – Place child components so that they are evenly spaced across the main axis, without any free space both before the first child component and after the last child component

When it comes to adding child components to either a Column or Row, we can do so by declaring these children within the children block, as shown below:

Column(
    arrangement = Arrangement.SpaceEvenly,
    modifier = Size(width = 200.dp, height = 100.dp)
) {
    Text("One")
    Text("Two")
    Text("Three")
}

If we dive under the hood for both of the Column and Row components, we can see some big similarities between the two:

@Composable
fun Column(
    ...
) {
    FlexLayout(
        orientation = LayoutOrientation.Vertical,
        modifier = modifier,
        arrangement = arrangement,
        crossAxisAlignment = CrossAxisAlignment.Start,
        crossAxisSize = LayoutSize.Wrap,
        children = { ColumnScope().children() }
    )
}

@Composable
fun Row(
    ...
) {
    FlexLayout(
        orientation = LayoutOrientation.Horizontal,
        modifier = modifier,
        arrangement = arrangement,
        crossAxisAlignment = CrossAxisAlignment.Start,
        crossAxisSize = LayoutSize.Wrap,
        children = { RowScope().children() }
    )
}

Both of these Row and Column components construct an instance of a FlexLayout, with the only difference being the orientation which is assigned to each one. The FlexLayout is accessed via a private function, so one of these cannot be constructed by yourself – we’ll dive into the technicalities of this layout in another article.

The Row and Column functions act as a gateway for creating a FlexLayout, using the respective orientation in place to do so. The FlexLayout will then be responsible for the drawing of our views in their corresponding positions.


In this article we’ve looked at the Row and Column components and how they can be used to lay out child components on the screen. In the next article we’ll take a look at the FlexRow and FlexColumn layouts which allow us to use weighting to lay out child components.

If you have any questions on how the Row / Column work, please feel free to reach out!

[twitter-follow screen_name=’hitherejoe’ show_count=’yes’]

About the author

hitherejoe

Add Comment

By hitherejoe