Button và IconButton
Hướng dẫn sử dụng các loại Button trong Compose Multiplatform.
Các loại Button
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun 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
@Composable
fun Example() {
Column {
AppButton(
text = "Login",
onClick = { },
leadingIcon = Icons.Default.Login
)
AppButton(
text = "Loading...",
onClick = { },
isLoading = true
)
}
}📝 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
Học về Layout - Row, Column, Box.
Last updated on