图标按钮显示用户可以执行的操作。图标按钮必须使用含义清晰的图标,并且通常代表常用或频繁执行的操作。
图标按钮有两种类型
- 默认: 这些按钮可以打开其他元素,例如菜单或搜索。
- 切换: 这些按钮可以表示可以开启或关闭的二元操作,例如“收藏”或“书签”。

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
的onClick
lambda 定义了按钮被点击时的行为,将状态在true
和false
之间切换。Icon
可组合项的painter
参数根据isToggled
状态有条件地加载不同的painterResource
。这会改变图标的视觉外观。- 如果
isToggled
为true
,则加载填充的心形 drawable。 - 如果
isToggled
为false
,则加载带轮廓的心形 drawable。
- 如果
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
(按钮未按下时图标的 drawable 资源 ID)和一个selectedImage: Int
(按钮按下时图标的 drawable 资源 ID)。- 它使用
interactionSource
来专门跟踪用户的“按下”互动。 - 当按钮处于活动按下状态时
isPressed
为 true,否则为 false。当isPressed
为true
时,LaunchedEffect
进入循环。- 在此循环中,它使用
delay
(与stepDelay
配合使用)来在触发操作之间创建暂停。coerceIn
确保延迟至少为 1 毫秒,以防止无限循环。 - 循环中每次延迟后都会调用
pressedListener
。这使得操作重复执行。
- 在此循环中,它使用
pressedListener
使用rememberUpdatedState
来确保onClick
lambda(要执行的操作)始终是最新组合中的最新版本。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