Bỏ qua để đến nội dung

Layout - Row, Column, Box

Hướng dẫn sử dụng các layout cơ bản trong Compose Multiplatform.

@Composable
fun ColumnExample() {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
@Composable
fun ColumnArrangements() {
val items = listOf("A", "B", "C")
Row(modifier = Modifier.fillMaxWidth()) {
// Top (default)
Column(
modifier = Modifier.weight(1f).height(200.dp).background(Color.LightGray),
verticalArrangement = Arrangement.Top
) {
items.forEach { Text(it) }
}
// Center
Column(
modifier = Modifier.weight(1f).height(200.dp).background(Color.Gray),
verticalArrangement = Arrangement.Center
) {
items.forEach { Text(it) }
}
// Bottom
Column(
modifier = Modifier.weight(1f).height(200.dp).background(Color.DarkGray),
verticalArrangement = Arrangement.Bottom
) {
items.forEach { Text(it, color = Color.White) }
}
// SpaceBetween
Column(
modifier = Modifier.weight(1f).height(200.dp).background(Color.LightGray),
verticalArrangement = Arrangement.SpaceBetween
) {
items.forEach { Text(it) }
}
// SpaceEvenly
Column(
modifier = Modifier.weight(1f).height(200.dp).background(Color.Gray),
verticalArrangement = Arrangement.SpaceEvenly
) {
items.forEach { Text(it) }
}
}
}

@Composable
fun RowExample() {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.Menu, contentDescription = null)
Text("Title")
Icon(Icons.Default.Settings, contentDescription = null)
}
}
@Composable
fun RowWithWeight() {
Row(modifier = Modifier.fillMaxWidth()) {
// Chiếm 1 phần
Box(
modifier = Modifier
.weight(1f)
.height(50.dp)
.background(Color.Red)
)
// Chiếm 2 phần
Box(
modifier = Modifier
.weight(2f)
.height(50.dp)
.background(Color.Green)
)
// Chiếm 1 phần
Box(
modifier = Modifier
.weight(1f)
.height(50.dp)
.background(Color.Blue)
)
}
}

@Composable
fun BoxExample() {
Box(
modifier = Modifier
.size(200.dp)
.background(Color.LightGray)
) {
// Bottom layer
Text(
"Bottom",
modifier = Modifier.align(Alignment.BottomStart)
)
// Middle layer
Box(
modifier = Modifier
.size(100.dp)
.background(Color.Blue)
.align(Alignment.Center)
)
// Top layer
Text(
"Top",
modifier = Modifier.align(Alignment.TopEnd),
color = Color.White
)
}
}
@Composable
fun BoxAlignments() {
Box(
modifier = Modifier
.size(200.dp)
.background(Color.LightGray)
) {
Text("TopStart", Modifier.align(Alignment.TopStart))
Text("TopCenter", Modifier.align(Alignment.TopCenter))
Text("TopEnd", Modifier.align(Alignment.TopEnd))
Text("CenterStart", Modifier.align(Alignment.CenterStart))
Text("Center", Modifier.align(Alignment.Center))
Text("CenterEnd", Modifier.align(Alignment.CenterEnd))
Text("BottomStart", Modifier.align(Alignment.BottomStart))
Text("BottomCenter", Modifier.align(Alignment.BottomCenter))
Text("BottomEnd", Modifier.align(Alignment.BottomEnd))
}
}

@Composable
fun SpacerExamples() {
Column {
Text("Item 1")
Spacer(Modifier.height(16.dp))
Text("Item 2")
Spacer(Modifier.height(32.dp))
Text("Item 3")
}
Row {
Text("Left")
Spacer(Modifier.weight(1f)) // Push to edges
Text("Right")
}
}

@Composable
fun ModifierOrderExample() {
Row {
// Padding THEN background
Box(
modifier = Modifier
.padding(16.dp)
.background(Color.Red)
.size(50.dp)
)
// Background THEN padding
Box(
modifier = Modifier
.background(Color.Blue)
.padding(16.dp)
.size(50.dp)
)
}
}

@Composable
fun CardLayout() {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp)
) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Avatar
Box(
modifier = Modifier
.size(48.dp)
.background(Color.Gray, CircleShape),
contentAlignment = Alignment.Center
) {
Text("JD", color = Color.White)
}
Spacer(Modifier.width(16.dp))
// Content
Column(modifier = Modifier.weight(1f)) {
Text("John Doe", fontWeight = FontWeight.Bold)
Text("john@example.com", color = Color.Gray)
}
// Action
IconButton(onClick = { }) {
Icon(Icons.Default.ChevronRight, contentDescription = null)
}
}
}
}
@Composable
fun ScreenLayout() {
Column(modifier = Modifier.fillMaxSize()) {
// Header
TopAppBar(
title = { Text("Screen Title") }
)
// Content - takes remaining space
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
) {
// Main content here
Text("Content", modifier = Modifier.align(Alignment.Center))
}
// Footer
BottomAppBar {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
IconButton(onClick = { }) {
Icon(Icons.Default.Home, contentDescription = "Home")
}
IconButton(onClick = { }) {
Icon(Icons.Default.Search, contentDescription = "Search")
}
IconButton(onClick = { }) {
Icon(Icons.Default.Person, contentDescription = "Profile")
}
}
}
}
}
@Composable
fun OverlayPattern() {
Box(modifier = Modifier.fillMaxSize()) {
// Main content
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(50) { index ->
Text("Item $index", modifier = Modifier.padding(16.dp))
}
}
// FAB overlay
FloatingActionButton(
onClick = { },
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(16.dp)
) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
// Loading overlay
if (false) { // isLoading
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.5f)),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
}

Layout Mục đích
Column Xếp children theo chiều dọc
Row Xếp children theo chiều ngang
Box Xếp chồng children
Spacer Tạo khoảng trống
Modifier Mô tả
weight() Chia tỷ lệ trong Row/Column
align() Căn chỉnh trong Box
fillMaxSize/Width/Height Fill parent
padding() Thêm padding

Học về LazyColumn và LazyRow.