Recommended resources
The freely available resources this lesson will direct you to.
Hello! Last time, you created reusable AccountBalance and TransactionSummary composables. They display different values, but your BankingSample still presents them as a plain vertical sequence. This lesson gives those elements a deliberate layout: a header, account rows, transaction rows, and readable space between sections. You’ll work with Column, Row, Box, and spacing modifiers while keeping the screen static.
Choose a layout for each relationship
A banking screen has several kinds of spatial relationships. Accounts belong below a heading; an account name and its balance belong beside each other; two labels in a header might occupy different corners of the same area. Compose provides three basic containers for these jobs:
Columnplaces children vertically.Rowplaces children horizontally.Boxplaces children in the same area, where they can be aligned independently or layered.
Watch how changing the container changes the direction and positioning of its children. The video uses some styling and preview code that you do not need to copy.
Rows and Columns - Jetpack Compose
Watch “Rows and Columns - Jetpack Compose” by Stevdza-San for a visual demonstration of the two layout directions and their positioning options.
Watch Column positioning for horizontalAlignment and verticalArrangement, then space between for an example of distributing spare room. Skip ahead to Row positioning to see how the corresponding arguments change for a horizontal layout. You can ignore the discussion of weighted items; this screen does not need them.
Notice the two axes. A Column arranges children along its vertical axis and aligns them along its horizontal axis. A Row does the reverse: its arrangement is horizontal, and its alignment is vertical. For example, Arrangement.SpaceBetween can put a name near the start of a wide row and an amount near its end. It needs spare horizontal space to distribute, so giving the row a useful width matters.
Android Developers’ Compose layout basics also shows Box, which serves a different purpose from either directional layout.
Compose layout basics | Jetpack Compose
Read Android Developers’ explanation of the three standard layout containers. Use its illustrations to distinguish placing children in sequence from placing them in the same area.
In “Standard layout components,” start at the paragraph explaining why two unarranged text elements overlap. Read standard layouts through the paragraph after the comparison illustration. Focus on the Column, Row, and Box examples. Then read the final paragraph and code example in that section, beginning “To set children's position within a Row,” for the arrangement and alignment argument names.
A Box is useful for our header because it can hold one label at the top-start and another at the bottom-end. Unlike a Column, it does not reserve a separate vertical slot for each child. If children occupy the same position, they may overlap; in our example, we will align them to different corners and give the Box enough height to make those corners distinct.
Give the containers room—and give the content breathing room
The previous BankingSample used a Column without specifying its width or padding. Modifiers let you adjust those layout properties. Modifier.fillMaxWidth() asks an element to use its available width; Modifier.padding(16.dp) adds space around its content. Here, dp is Compose’s density-independent unit for layout dimensions.
For gaps between children, you have two useful choices. A Column can use verticalArrangement = Arrangement.spacedBy(8.dp) to put a consistent gap between every pair of children. A Spacer is itself an empty child: Spacer(Modifier.height(12.dp)) makes an intentionally larger break at one particular spot. These solve different problems—regular rhythm versus a section break.
Compose layout basics | Jetpack Compose
Continue in Android Developers’ Compose layout basics to see a layout with chained modifiers and a Spacer.
In “Using modifiers in your layouts,” read layout modifiers through the sentence following the illustrated example. Look specifically for padding, fillMaxWidth, and Spacer; the example’s click behavior and card styling are not needed today. Stop before “Scrollable layouts.”
In our screen, the outer Column will fill the available width and have padding around its contents. Each account and transaction Row will also fill the width available inside that padded column. Only then can Arrangement.SpaceBetween visibly separate its two texts.
Arrange the banking sample
Open the file where you defined AccountBalance, TransactionSummary, and BankingSample last time. Keep your existing package declaration. Replace those three functions with the following version, adding the imports you do not already have. Leave MainActivity calling BankingSample() inside its existing setContent and theme wrapper.
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun AccountBalance(
accountName: String,
balanceText: String,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(text = "$accountName balance")
Text(text = balanceText)
}
}
@Composable
fun TransactionSummary(
description: String,
amountText: String,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(text = description)
Text(text = amountText)
}
}
@Composable
fun BankingSample() {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
) {
Text(
text = "Account overview",
modifier = Modifier.align(Alignment.TopStart)
)
Text(
text = "Sample amounts",
modifier = Modifier.align(Alignment.BottomEnd)
)
}
Text(text = "Accounts")
AccountBalance(
accountName = "Checking",
balanceText = "2,450.00 USD"
)
AccountBalance(
accountName = "Savings",
balanceText = "800.00 USD"
)
Spacer(modifier = Modifier.height(12.dp))
Text(text = "Recent transactions")
TransactionSummary(
description = "Groceries",
amountText = "-18.50 USD"
)
TransactionSummary(
description = "Deposit",
amountText = "+125.00 USD"
)
}
}
Read the result from the outside inward. The Column establishes the screen’s top-to-bottom order. Its padding(16.dp) keeps the content away from the screen edges, while spacedBy(8.dp) supplies the ordinary gaps. The Spacer is an additional child between the account and transaction sections, making that break larger than the regular gaps.
Inside each row, fillMaxWidth() provides room for SpaceBetween to work. The first text sits toward the row’s start and the second toward its end. verticalAlignment = Alignment.CenterVertically keeps them aligned if one child becomes taller than the other. The optional modifier parameter also lets a caller adjust either reusable element later without editing its internal layout.
Finally, the Box is 64 dp high and as wide as the content area. Its two Text children use Modifier.align to select different corners within that box. Their positions come from the Box, not from the order of the surrounding Column.
Run the app on the emulator. You should see account names opposite balances and transaction descriptions opposite amounts, with a clearer break between the two groups. If an amount remains close to its label instead of appearing toward the far side, check that the Row has fillMaxWidth(). Without spare width, SpaceBetween has little space to distribute.
This remains a compact, non-scrolling sample screen. Long descriptions could crowd an amount in a row; handling larger transaction collections and varied screen sizes comes later. For now, the goal is to make the placement of these sample elements understandable and intentional.
What you’ve established
You can now choose Column for vertical groups, Row for side-by-side values, and Box for independently positioned or layered children. Arrangement and alignment control placement inside a container; fillMaxWidth, padding, and Spacer control how much room it has and where gaps appear.
The interface has structure, but little visual treatment. Next, you’ll apply Material 3 components and modifiers to make this static banking screen more polished while preserving the layout you built here.