圖示按鈕會顯示使用者可採取的動作。圖示按鈕必須使用具有明確意義的圖示,通常代表常見或常用的動作。
圖示按鈕分為兩種:
- 預設:這些按鈕可開啟其他元素,例如選單或搜尋功能。
- 切換鈕:這些按鈕可代表可切換開啟或關閉的二元動作,例如「收藏」或「書籤」。
API 介面
使用 IconButton 可組合項實作標準圖示按鈕。如要建立不同的視覺樣式 (例如填滿、填滿色調或外框),請分別使用 FilledIconButton、FilledTonalIconButton 和 OutlinedIconButton。
IconButton 的關鍵參數包括:
onClick:使用者輕觸圖示按鈕時執行的 lambda 函式。enabled:用來控制按鈕啟用狀態的布林值。當false時,按鈕不會回應使用者輸入內容。content:按鈕內的可組合內容,通常是Icon。
基本範例:切換圖示按鈕
本範例說明如何實作切換圖示按鈕。切換圖示按鈕會根據是否已選取而變更外觀。
@Preview @Composable fun ToggleIconButtonExample() { // isToggled initial value should be read from a view model or persistent storage. var isToggled by rememberSaveable { mutableStateOf(false) } IconButton( onClick = { isToggled = !isToggled } ) { Icon( painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite), contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button." ) } }
程式碼的重點
ToggleIconButtonExample可組合函式定義可切換的IconButton。mutableStateOf(false)會建立一個MutableState物件,該物件會保留布林值,最初為false。這會讓isToggled成為狀態容器,也就是說,只要值有所變更,Compose 就會重新組合 UI。rememberSaveable可確保isToggled狀態在螢幕旋轉等設定變更後持續存在。
IconButton的onClicklambda 會定義按鈕在按下時的行為,在true和false之間切換狀態。Icon可組合函式的painter參數會根據isToggled狀態,有條件地載入不同的painterResource。這會變更圖示的視覺外觀。- 如果
isToggled是true,則會載入填滿的心形可繪項目。 - 如果
isToggled為false,則會載入帶有輪廓的愛心可繪項目。
- 如果
Icon的contentDescription也會根據isToggled狀態更新,提供適當的無障礙資訊。
結果
下圖顯示前述程式碼片段中的切換圖示按鈕,處於未選取狀態:

進階範例:按下按鈕時重複執行動作
本節將說明如何建立圖示按鈕,讓使用者按住按鈕時持續觸發動作,而非每次點選觸發一次。
@Composable fun MomentaryIconButton( unselectedImage: Int, selectedImage: Int, contentDescription: String, modifier: Modifier = Modifier, stepDelay: Long = 100L, // Minimum value is 1L milliseconds. onClick: () -> Unit ) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() val pressedListener by rememberUpdatedState(onClick) LaunchedEffect(isPressed) { while (isPressed) { delay(stepDelay.coerceIn(1L, Long.MAX_VALUE)) pressedListener() } } IconButton( modifier = modifier, onClick = onClick, interactionSource = interactionSource ) { Icon( painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage), contentDescription = contentDescription, ) } }
程式碼的重點
MomentaryIconButton會使用unselectedImage: Int,這是未按下按鈕時圖示的可繪製資源 ID,以及selectedImage: Int,這是按下按鈕時圖示的可繪製資源 ID。- 它會使用
interactionSource來追蹤使用者「按下」的互動。 - 當按鈕處於按壓狀態時,
isPressed會設為 true,否則為 false。當isPressed為true時,LaunchedEffect會進入迴圈。- 在這個迴圈中,它會使用
delay(搭配stepDelay) 在觸發動作之間建立暫停時間。coerceIn可確保延遲時間至少為 1 毫秒,以免發生無限迴圈。 - 系統會在迴圈內每次延遲後呼叫
pressedListener。這會導致動作重複執行。
- 在這個迴圈中,它會使用
pressedListener會使用rememberUpdatedState,確保onClicklambda (要執行的動作) 一律來自最新的組合。Icon會根據按鈕目前是否按下,變更顯示的圖片。- 如果
isPressed為 true,就會顯示selectedImage。 - 否則會顯示
unselectedImage。
- 如果
接著,在範例中使用這個 MomentaryIconButton。以下程式碼片段示範控制計數器的兩個圖示按鈕:
@Preview() @Composable fun MomentaryIconButtonExample() { var pressedCount by remember { mutableIntStateOf(0) } Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { MomentaryIconButton( unselectedImage = R.drawable.fast_rewind, selectedImage = R.drawable.fast_rewind_filled, stepDelay = 100L, onClick = { pressedCount -= 1 }, contentDescription = "Decrease count button" ) Spacer(modifier = Modifier) Text("advanced by $pressedCount frames") Spacer(modifier = Modifier) MomentaryIconButton( unselectedImage = R.drawable.fast_forward, selectedImage = R.drawable.fast_forward_filled, contentDescription = "Increase count button", stepDelay = 100L, onClick = { pressedCount += 1 } ) } }
程式碼的重點
MomentaryIconButtonExample可組合函式會顯示Row,其中包含兩個MomentaryIconButton例項和Text可組合函式,用於建構用來遞增和遞減計數器的 UI。- 它會使用
remember和mutableIntStateOf維護pressedCount可變動狀態變數,並將其初始化為 0。當pressedCount變更時,任何觀察它的可組合項 (例如Text可組合項) 都會重新組合,以反映新的值。 - 第一個
MomentaryIconButton在點選或按住時會減少pressedCount。 - 第二個
MomentaryIconButton在按下或按住時會增加pressedCount。 - 兩個按鈕都使用 100 毫秒的
stepDelay,也就是說,按住按鈕時,onClick動作會每隔 100 毫秒重複一次。
結果
以下影片顯示含有圖示按鈕和計數器的 UI: