Android Compose UI 按鈕與互動元件 (Button, Clickable, Ripple)

在 App 中,按鈕是最常見的互動元件。Compose 提供了多種按鈕樣式,並允許我們自定義點擊行為。

基礎按鈕 (Button)

最標準的實心按鈕。

Button(
    onClick = { /* 點擊事件處理 */ },
    enabled = true, // 是否啟用
    shape = RoundedCornerShape(8.dp), // 形狀
    colors = ButtonDefaults.buttonColors(
        containerColor = Color.Blue,
        contentColor = Color.White
    ),
    elevation = ButtonDefaults.buttonElevation(8.dp)
) {
    // 內容 (可以是 Row, Icon + Text 等)
    Icon(Icons.Filled.Favorite, contentDescription = null)
    Spacer(Modifier.size(8.dp))
    Text("Like")
}

其他變體

  • FilledTonalButton:中等強調的按鈕 (淺色背景)。
  • OutlinedButton:只有邊框的按鈕。
  • TextButton:只有文字的按鈕 (常用於 Dialog 中的確認/取消)。
  • ElevatedButton:有陰影的按鈕。

原則上,一個畫面中應該只有一個主要的 Button,其他的則依重要性使用 OutlinedButtonTextButton

任何元件皆可點擊 (Modifier.clickable)

不只是 Button,任何 Composable (如 Text, Image, Row) 只要加上 Modifier.clickable 就能變成可點擊的。

Image(
    painter = painterResource(id = R.drawable.my_image),
    contentDescription = null,
    modifier = Modifier
        .clip(CircleShape)
        .clickable(
            onClick = { /* Handle click */ }
        )
)
加上 clickable 的元件會自動獲得水波紋效果 (Ripple Effect),這對使用者體驗很重要,因為它提供了視覺回饋。

水波紋效果 (Ripple Effect)

Compose 會根據 Material Design 規範自動處理水波紋。

移除水波紋

有時候我們不想要有水波紋(例如點擊單純的文字連結),可以使用 indication = null

Text(
    "Click me",
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null // 移除點擊視覺效果
    ) {
        // ...
    }
)

互動狀態 (InteractionSource)

如果你想要根據互動狀態(例如:按下時、Focus 時、Hover 時)改變元件外觀,可以使用 InteractionSource

val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()

val scale = if (isPressed) 0.9f else 1.0f // 按下時縮小

Button(
    onClick = {},
    interactionSource = interactionSource,
    modifier = Modifier.scale(scale)
) {
    Text("Press me")
}

小結

  • 依據功能重要性選擇合適的 Button 類型。
  • 使用 Modifier.clickable 讓任何元件變身按鈕。
  • 注意點擊時的視覺回饋 (Ripple),這是良好 UX 的關鍵。