Button và IconButton
Hướng dẫn sử dụng các loại Button trong Compose Multiplatform.
Các loại Button
Phần tiêu đề “Các loại Button”@Composablefun ButtonTypes() { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { // Filled Button (Primary) Button(onClick = { }) { Text("Filled Button") }
// Outlined Button OutlinedButton(onClick = { }) { Text("Outlined Button") }
// Text Button TextButton(onClick = { }) { Text("Text Button") }
// Elevated Button ElevatedButton(onClick = { }) { Text("Elevated Button") }
// Filled Tonal Button FilledTonalButton(onClick = { }) { Text("Tonal Button") } }}Button với Icon
Phần tiêu đề “Button với Icon”@Composablefun ButtonsWithIcons() { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { // Icon ở đầu Button(onClick = { }) { Icon( Icons.Default.Add, contentDescription = null, modifier = Modifier.size(18.dp) ) Spacer(Modifier.width(8.dp)) Text("Add Item") }
// Icon ở cuối Button(onClick = { }) { Text("Next") Spacer(Modifier.width(8.dp)) Icon( Icons.Default.ArrowForward, contentDescription = null, modifier = Modifier.size(18.dp) ) }
// Outlined với icon OutlinedButton(onClick = { }) { Icon(Icons.Default.Share, contentDescription = null) Spacer(Modifier.width(8.dp)) Text("Share") } }}IconButton
Phần tiêu đề “IconButton”@Composablefun IconButtons() { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { // Standard IconButton IconButton(onClick = { }) { Icon(Icons.Default.Favorite, contentDescription = "Like") }
// Filled IconButton FilledIconButton(onClick = { }) { Icon(Icons.Default.Add, contentDescription = "Add") }
// Outlined IconButton OutlinedIconButton(onClick = { }) { Icon(Icons.Default.Edit, contentDescription = "Edit") }
// Tonal IconButton FilledTonalIconButton(onClick = { }) { Icon(Icons.Default.Share, contentDescription = "Share") } }}Toggle IconButton
Phần tiêu đề “Toggle IconButton”@Composablefun ToggleIconButtonExample() { var isFavorite by remember { mutableStateOf(false) }
IconButton( onClick = { isFavorite = !isFavorite } ) { Icon( imageVector = if (isFavorite) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder, contentDescription = "Favorite", tint = if (isFavorite) Color.Red else Color.Gray ) }}Floating Action Button
Phần tiêu đề “Floating Action Button”@Composablefun FABExamples() { Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { // Standard FAB FloatingActionButton(onClick = { }) { Icon(Icons.Default.Add, contentDescription = "Add") }
// Small FAB SmallFloatingActionButton(onClick = { }) { Icon(Icons.Default.Add, contentDescription = "Add") }
// Large FAB LargeFloatingActionButton(onClick = { }) { Icon( Icons.Default.Add, contentDescription = "Add", modifier = Modifier.size(36.dp) ) }
// Extended FAB ExtendedFloatingActionButton( onClick = { }, icon = { Icon(Icons.Default.Add, contentDescription = null) }, text = { Text("Create") } ) }}Custom Button Styling
Phần tiêu đề “Custom Button Styling”@Composablefun CustomStyledButtons() { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { // Custom colors Button( onClick = { }, colors = ButtonDefaults.buttonColors( containerColor = Color(0xFF6200EE), contentColor = Color.White ) ) { Text("Custom Color") }
// Custom shape Button( onClick = { }, shape = RoundedCornerShape(50) // Pill shape ) { Text("Rounded Button") }
// Full width Button( onClick = { }, modifier = Modifier .fillMaxWidth() .height(56.dp), shape = RoundedCornerShape(12.dp) ) { Text("Full Width Button") }
// Gradient button Box( modifier = Modifier .fillMaxWidth() .height(56.dp) .background( brush = Brush.horizontalGradient( colors = listOf(Color(0xFF6200EE), Color(0xFFBB86FC)) ), shape = RoundedCornerShape(12.dp) ) .clickable { }, contentAlignment = Alignment.Center ) { Text("Gradient Button", color = Color.White) } }}Button States
Phần tiêu đề “Button States”@Composablefun ButtonWithStates() { var isLoading by remember { mutableStateOf(false) }
Button( onClick = { isLoading = true // Simulate loading }, enabled = !isLoading, modifier = Modifier .fillMaxWidth() .height(56.dp) ) { if (isLoading) { CircularProgressIndicator( modifier = Modifier.size(24.dp), color = MaterialTheme.colorScheme.onPrimary, strokeWidth = 2.dp ) } else { Text("Submit") } }}Disabled states
Phần tiêu đề “Disabled states”@Composablefun DisabledButtons() { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { Button( onClick = { }, enabled = false ) { Text("Disabled Filled") }
OutlinedButton( onClick = { }, enabled = false ) { Text("Disabled Outlined") }
TextButton( onClick = { }, enabled = false ) { Text("Disabled Text") } }}Reusable Button Component
Phần tiêu đề “Reusable Button Component”@Composablefun AppButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, isLoading: Boolean = false, leadingIcon: ImageVector? = null, trailingIcon: ImageVector? = null) { Button( onClick = onClick, modifier = modifier.height(52.dp), enabled = enabled && !isLoading, shape = RoundedCornerShape(12.dp) ) { if (isLoading) { CircularProgressIndicator( modifier = Modifier.size(20.dp), color = MaterialTheme.colorScheme.onPrimary, strokeWidth = 2.dp ) } else { leadingIcon?.let { Icon(it, contentDescription = null, modifier = Modifier.size(20.dp)) Spacer(Modifier.width(8.dp)) }
Text(text, style = MaterialTheme.typography.labelLarge)
trailingIcon?.let { Spacer(Modifier.width(8.dp)) Icon(it, contentDescription = null, modifier = Modifier.size(20.dp)) } } }}
// Sử dụng@Composablefun Example() { Column { AppButton( text = "Login", onClick = { }, leadingIcon = Icons.Default.Login )
AppButton( text = "Loading...", onClick = { }, isLoading = true ) }}📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Button Type | Use Case |
|---|---|
Button |
Primary action |
OutlinedButton |
Secondary action |
TextButton |
Low emphasis |
ElevatedButton |
Medium emphasis |
FilledTonalButton |
Medium emphasis, softer |
FloatingActionButton |
Main screen action |
IconButton |
Icon-only actions |
Tiếp theo
Phần tiêu đề “Tiếp theo”Học về Layout - Row, Column, Box.