Organiza tus páginas con colecciones
Guarda y categoriza el contenido según tus preferencias.
Los botones de íconos muestran las acciones que los usuarios pueden realizar. Los botones de íconos deben usar un ícono con un significado claro y, por lo general, representan acciones comunes o de uso frecuente.
Existen dos tipos de botones de íconos:
Predeterminado: Estos botones pueden abrir otros elementos, como un menú o una búsqueda.
Botón de activación: Estos botones pueden representar acciones binarias que se pueden activar o desactivar, como "favorito" o "marcador".
Figura 1: Botones de íconos, algunos de los cuales están rellenos (lo que indica que están seleccionados) y con contorno.
Entre los parámetros clave de IconButton, se incluyen los siguientes:
onClick: Es una función lambda que se ejecuta cuando el usuario presiona el botón del ícono.
enabled: Es un valor booleano que controla el estado habilitado del botón. Cuando false, el botón no responde a la entrada del usuario.
content: Es el contenido componible dentro del botón, por lo general, un Icon.
Ejemplo básico: Botón de activación de ícono
En este ejemplo, se muestra cómo implementar un botón de ícono de activación. Un botón de ícono de activación cambia su apariencia según si está seleccionado o no.
@Preview@ComposablefunToggleIconButtonExample(){// isToggled initial value should be read from a view model or persistent storage.varisToggledbyrememberSaveable{mutableStateOf(false)}IconButton(onClick={isToggled=!isToggled}){Icon(painter=if(isToggled)painterResource(R.drawable.favorite_filled)elsepainterResource(R.drawable.favorite),contentDescription=if(isToggled)"Selected icon button"else"Unselected icon button.")}}
El elemento componible ToggleIconButtonExample define un IconButton conmutable.
mutableStateOf(false) crea un objeto MutableState que contiene un valor booleano, inicialmente false. Esto hace que isToggled sea un contenedor de estado, lo que significa que Compose recompone la IU cada vez que cambia su valor.
rememberSaveable garantiza que el estado isToggled persista en todos los cambios de configuración, como la rotación de pantalla.
La lambda onClick de IconButton define el comportamiento del botón cuando se hace clic en él, alternando el estado entre true y false.
El parámetro painter del elemento componible Icon carga de forma condicional un painterResource diferente según el estado isToggled. Esto cambia la apariencia visual del ícono.
Si isToggled es true, carga el elemento de diseño de corazón relleno.
Si isToggled es false, carga el elemento de diseño de corazón delineado.
El contentDescription de Icon también se actualiza según el estado de isToggled para proporcionar la información de accesibilidad adecuada.
Resultado
En la siguiente imagen, se muestra el botón del ícono de activación del fragmento anterior en su estado no seleccionado:
Figura 2: Un botón de ícono de activación "favorito" en su estado no seleccionado.
Ejemplo avanzado: Acciones repetidas al presionar
En esta sección, se muestra cómo crear botones de íconos que activen una acción de forma continua mientras el usuario los mantiene presionados, en lugar de activarse solo una vez por clic.
@ComposablefunMomentaryIconButton(unselectedImage:Int,selectedImage:Int,contentDescription:String,modifier:Modifier=Modifier,stepDelay:Long=100L,// Minimum value is 1L milliseconds.onClick:()->Unit){valinteractionSource=remember{MutableInteractionSource()}valisPressedbyinteractionSource.collectIsPressedAsState()valpressedListenerbyrememberUpdatedState(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)elsepainterResource(id=unselectedImage),contentDescription=contentDescription,)}}
MomentaryIconButton toma un unselectedImage: Int, el ID de recurso de diseño del ícono cuando no se presiona el botón, y selectedImage: Int, el ID de recurso de diseño del ícono cuando se presiona el botón.
Usa un interactionSource para hacer un seguimiento específico de las interacciones de "presionar" del usuario.
isPressed es verdadero cuando se presiona el botón de forma activa y es falso en caso contrario. Cuando isPressed es true, LaunchedEffect entra en un bucle.
Dentro de este bucle, usa un delay (con stepDelay) para crear pausas entre las acciones de activación. coerceIn garantiza que la demora sea de al menos 1 ms para evitar bucles infinitos.
Se invoca pressedListener después de cada demora dentro del bucle. Esto hace que se repita la acción.
pressedListener usa rememberUpdatedState para garantizar que la lambda onClick (la acción que se debe realizar) siempre sea la más actualizada de la composición más reciente.
Icon cambia su imagen según si el botón está presionado o no.
Si isPressed es verdadero, se muestra selectedImage.
De lo contrario, se muestra unselectedImage.
A continuación, usa este MomentaryIconButton en un ejemplo. En el siguiente fragmento, se muestran dos botones de ícono que controlan un contador:
@Preview()@ComposablefunMomentaryIconButtonExample(){varpressedCountbyremember{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})}}
El elemento componible MomentaryIconButtonExample muestra un Row que contiene dos instancias de MomentaryIconButton y un elemento componible Text para compilar una IU para incrementar y disminuir un contador.
Mantiene una variable de estado mutable pressedCount con remember y mutableIntStateOf, inicializada en 0. Cuando cambia pressedCount, se vuelven a componer los elementos componibles que lo observan (como el elemento Text componible) para reflejar el valor nuevo.
El primer MomentaryIconButton disminuye pressedCount cuando se hace clic en él o se mantiene presionado.
El segundo MomentaryIconButton aumenta pressedCount cuando se hace clic en él o se mantiene presionado.
Ambos botones usan un stepDelay de 100 milisegundos, lo que significa que la acción onClick se repite cada 100 ms mientras se mantiene presionado un botón.
Resultado
En el siguiente video, se muestra la IU con los botones de íconos y el contador:
Figura 3. IU de un contador con dos botones de íconos (más y menos) que aumentan y disminuyen el contador.
El contenido y las muestras de código que aparecen en esta página están sujetas a las licencias que se describen en la Licencia de Contenido. Java y OpenJDK son marcas registradas de Oracle o sus afiliados.
Última actualización: 2025-08-28 (UTC)
[null,null,["Última actualización: 2025-08-28 (UTC)"],[],[],null,["Icon buttons display actions that users can take. Icon buttons must use an icon\nwith a clear meaning, and typically represent common or frequently used actions.\n\nThere are two types of icon buttons:\n\n- **Default**: These buttons can open other elements, such as a menu or search.\n- **Toggle**: These buttons can represent binary actions that can be toggled on or off, such as \"favorite\" or \"bookmark\".\n\n**Figure 1.** Icon buttons, some of which are filled (indicating selection) and outlined.\n\nAPI surface\n\nUse the [`IconButton`](/reference/kotlin/androidx/compose/material3/package-summary#IconButton(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.material3.IconButtonColors,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)) composable to implement standard icon buttons. To\ncreate different visual styles like filled, filled tonal, or outlined, use\n[`FilledIconButton`](/reference/kotlin/androidx/compose/material3/package-summary#FilledIconButton(kotlin.Function0,androidx.compose.material3.IconButtonShapes,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.material3.IconButtonColors,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function0)), [`FilledTonalIconButton`](/reference/kotlin/androidx/compose/material3/package-summary#FilledTonalIconButton(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.IconButtonColors,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function0)), and\n[`OutlinedIconButton`](/reference/kotlin/androidx/compose/material3/package-summary#OutlinedIconButton(kotlin.Function0,androidx.compose.material3.IconButtonShapes,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.material3.IconButtonColors,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function0)), respectively.\n\nThe key parameters for `IconButton` include:\n\n- `onClick`: A lambda function that executes when the user taps the icon button.\n- `enabled`: A boolean that controls the enabled state of the button. When `false`, the button does not respond to user input.\n- `content`: The composable content inside the button, typically an `Icon`.\n\nBasic example: Toggle icon button\n\nThis example shows you how to implement a toggle icon button. A toggle icon\nbutton changes its appearance based on whether it's selected or unselected.\n\n\n```kotlin\n@Preview\n@Composable\nfun ToggleIconButtonExample() {\n // isToggled initial value should be read from a view model or persistent storage.\n var isToggled by rememberSaveable { mutableStateOf(false) }\n\n IconButton(\n onClick = { isToggled = !isToggled }\n ) {\n Icon(\n painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite),\n contentDescription = if (isToggled) \"Selected icon button\" else \"Unselected icon button.\"\n )\n }\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/components/IconButton.kt#L44-L58\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- The `ToggleIconButtonExample` composable defines a toggleable `IconButton`.\n - `mutableStateOf(false)` creates a `MutableState` object that holds a boolean value, initially `false`. This makes `isToggled` a state holder, meaning Compose recomposes the UI whenever its value changes.\n - `rememberSaveable` ensures the `isToggled` state persists across configuration changes, like screen rotation.\n- The `onClick` lambda of the `IconButton` defines the button's behavior when clicked, toggling the state between `true` and `false`.\n- The [`Icon`](/reference/kotlin/androidx/compose/material3/package-summary#Icon(androidx.compose.ui.graphics.painter.Painter,kotlin.String,androidx.compose.ui.Modifier,androidx.compose.ui.graphics.Color)) composable's `painter` parameter conditionally loads a different `painterResource` based on the `isToggled` state. This changes the visual appearance of the icon.\n - If `isToggled` is `true`, it loads the filled heart drawable.\n - If `isToggled` is `false`, it loads the outlined heart drawable.\n- The `contentDescription` of the `Icon` also updates based on the `isToggled` state to provide appropriate accessibility information.\n\nResult\n\nThe following image shows the toggle icon button from the preceding snippet in\nits unselected state:\n**Figure 2.** A \"favorite\" toggle icon button in its unselected state.\n\nAdvanced example: Repeated actions on press\n\nThis section demonstrates how to create icon buttons that continuously trigger\nan action while the user presses and holds them, rather than just triggering\nonce per click.\n\n\n```kotlin\n@Composable\nfun MomentaryIconButton(\n unselectedImage: Int,\n selectedImage: Int,\n contentDescription: String,\n modifier: Modifier = Modifier,\n stepDelay: Long = 100L, // Minimum value is 1L milliseconds.\n onClick: () -\u003e Unit\n) {\n val interactionSource = remember { MutableInteractionSource() }\n val isPressed by interactionSource.collectIsPressedAsState()\n val pressedListener by rememberUpdatedState(onClick)\n\n LaunchedEffect(isPressed) {\n while (isPressed) {\n delay(stepDelay.coerceIn(1L, Long.MAX_VALUE))\n pressedListener()\n }\n }\n\n IconButton(\n modifier = modifier,\n onClick = onClick,\n interactionSource = interactionSource\n ) {\n Icon(\n painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage),\n contentDescription = contentDescription,\n )\n }\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/components/IconButton.kt#L62-L92\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- `MomentaryIconButton` takes an `unselectedImage: Int`, the drawable resource ID for the icon when the button is not pressed, and `selectedImage: Int`, the drawable resource ID for the icon when the button is pressed.\n- It uses an `interactionSource` to specifically track \"press\" interactions from the user.\n- `isPressed` is true when the button is actively being pressed and false otherwise. When `isPressed` is `true`, the `LaunchedEffect` enters a loop.\n - Inside this loop, it uses a `delay` (with `stepDelay`) to create pauses between triggering actions. `coerceIn` ensures the delay is at least 1ms to prevent infinite loops.\n - The `pressedListener` is invoked after each delay within the loop. This makes the action repeat.\n- The `pressedListener` uses `rememberUpdatedState` to ensure that the `onClick` lambda (the action to perform) is always the most up-to-date from the latest composition.\n- The `Icon` changes its displayed image based on whether the button is currently pressed or not.\n - If `isPressed` is true, the `selectedImage` is shown.\n - Otherwise, the `unselectedImage` is shown.\n\nNext, use this `MomentaryIconButton` in an example. The following snippet\ndemonstrates two icon buttons controlling a counter:\n\n\n```kotlin\n@Preview()\n@Composable\nfun MomentaryIconButtonExample() {\n var pressedCount by remember { mutableIntStateOf(0) }\n\n Row(\n modifier = Modifier.fillMaxWidth(),\n verticalAlignment = Alignment.CenterVertically\n ) {\n MomentaryIconButton(\n unselectedImage = R.drawable.fast_rewind,\n selectedImage = R.drawable.fast_rewind_filled,\n stepDelay = 100L,\n onClick = { pressedCount -= 1 },\n contentDescription = \"Decrease count button\"\n )\n Spacer(modifier = Modifier)\n Text(\"advanced by $pressedCount frames\")\n Spacer(modifier = Modifier)\n MomentaryIconButton(\n unselectedImage = R.drawable.fast_forward,\n selectedImage = R.drawable.fast_forward_filled,\n contentDescription = \"Increase count button\",\n stepDelay = 100L,\n onClick = { pressedCount += 1 }\n )\n }\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/components/IconButton.kt#L96-L123\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- The `MomentaryIconButtonExample` composable displays a `Row` containing two `MomentaryIconButton` instances and a `Text` composable to build a UI for incrementing and decrementing a counter.\n- It maintains a `pressedCount` mutable state variable using `remember` and `mutableIntStateOf`, initialized to 0. When `pressedCount` changes, any composables observing it (like the `Text` composable) recompose to reflect the new value.\n- The first `MomentaryIconButton` decreases `pressedCount` when clicked or held.\n- The second `MomentaryIconButton` increases `pressedCount` when clicked or held.\n- Both buttons use a `stepDelay` of 100 milliseconds, meaning the `onClick` action repeats every 100ms while a button is held.\n\nResult\n\nThe following video shows the UI with the icon buttons and the counter:\n**Figure 3**. A counter UI with two icon buttons (plus and minus) that increment and decrement the counter.\n\nAdditional resources\n\n- [Material 3 - Icon buttons](https://m3.material.io/components/icon-buttons/overview)"]]