In Jetpack Compose, layout composition is clean and intuitive. You do not write deeply nested XML files with multiple passes of layout_weight recalculations. Instead, you compose lightweight layout containers using Arrangements, Alignments, and Modifiers.
Every Row and Column layout container accepts two key spatial parameters:
Arrangement.SpaceBetween, SpaceEvenly, SpaceAround, Center, and spacedBy(8.dp).Alignment.CenterHorizontally, CenterVertically, Start, and End.@Composable
fun ActionToolbar() {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween, // Main Axis
verticalAlignment = Alignment.CenterVertically // Cross Axis
) {
Text("Dashboard", style = MaterialTheme.typography.titleLarge)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
IconButton(onClick = { /* Search */ }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { /* Settings */ }) {
Icon(Icons.Default.Settings, contentDescription = "Settings")
}
}
}
}
Modern Material Design applications follow standard screen scaffolds. Compose provides the Scaffold composable to structure your TopAppBar, Bottom Navigation bar, Floating Action Button, and SnackbarHost effortlessly:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreenScaffold() {
Scaffold(
topBar = {
TopAppBar(
title = { Text("Veewom Android") },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color(0xFF00B0FF),
titleContentColor = Color.White
)
)
},
floatingActionButton = {
FloatingActionButton(
onClick = { /* Add item */ },
containerColor = Color(0xFF00B0FF),
contentColor = Color.White
) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
},
bottomBar = {
NavigationBar {
NavigationBarItem(
selected = true,
onClick = { },
icon = { Icon(Icons.Default.Home, contentDescription = "Home") },
label = { Text("Home") }
)
NavigationBarItem(
selected = false,
onClick = { },
icon = { Icon(Icons.Default.Book, contentDescription = "Tutorials") },
label = { Text("Tutorials") }
)
}
}
) { innerPadding ->
// Content area respects system bars and app bar padding!
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.padding(16.dp)
) {
Text("Welcome to the modern Scaffold layout!")
}
}
}
For complex UI relationships where elements depend on multiple dynamic siblings, you can use androidx.constraintlayout.compose:constraintlayout-compose:
@Composable
fun ConstraintProfileHeader() {
ConstraintLayout(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
val (avatar, nameText, bioText, followBtn) = createRefs()
Image(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = "Avatar",
modifier = Modifier
.size(72.dp)
.constrainAs(avatar) {
top.linkTo(parent.top)
start.linkTo(parent.start)
}
)
Text(
text = "Android Masterclass",
fontWeight = FontWeight.Bold,
modifier = Modifier.constrainAs(nameText) {
top.linkTo(avatar.top)
start.linkTo(avatar.end, margin = 16.dp)
}
)
Button(
onClick = { },
modifier = Modifier.constrainAs(followBtn) {
top.linkTo(nameText.bottom, margin = 8.dp)
start.linkTo(avatar.end, margin = 16.dp)
}
) {
Text("Enroll Now")
}
}
}
Broaden your foundational and advanced Android application development skills across our curriculum:
Use Material 3 Scaffolds, TopAppBars, FloatingActionButtons, and Cards.
Construct efficient recycling vertical and horizontal list layouts.
Update layouts dynamically in response to state mutations.
Build real-world Compose layouts in our interactive project lab.