Skip to Content
Kotlin Multiplatform📚 Học KMPLayout - Row, Column, Box

Layout - Row, Column, Box

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

Column - Xếp dọc

@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") } }

Vertical Arrangement

@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) } } } }

Row - Xếp ngang

@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) } }

Weight modifier

@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) ) } }

Box - Xếp chồng

@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 ) } }

Box Alignment

@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)) } }

Spacer

@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") } }

Modifier Order Matters

@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) ) } }

Common Patterns

Card Layout

@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") } } } } }

Overlay Pattern

@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() } } } }

📝 Tóm tắt

LayoutMục đích
ColumnXếp children theo chiều dọc
RowXếp children theo chiều ngang
BoxXếp chồng children
SpacerTạo khoảng trống
ModifierMô tả
weight()Chia tỷ lệ trong Row/Column
align()Căn chỉnh trong Box
fillMaxSize/Width/HeightFill parent
padding()Thêm padding

Tiếp theo

Học về LazyColumn và LazyRow.

Last updated on