[ Web Proxy ]
URL:
Viewing: http://developer.android.com/develop/ui/compose/components/icon-button [Back]  [Original]

Icon buttons  |  Jetpack Compose  |  Android Developers Skip to main content
Essentials Design & Plan Develop Google Play Blog
Search:
Android Studio
Android Developers [Android Developers]

Icon buttons Stay organized with collections Save and categorize content based on your preferences.

Icon buttons display actions that users can take. Icon buttons must use an icon with a clear meaning, and typically represent common or frequently used actions.

There are two types of icon buttons:

5 icon buttons with different icons (settings, more, etc). Some are filled, indicating selection, and some are outlined. [5 icon buttons with different icons (settings, more, etc). Some are filled, indicating selection, and some are outlined.] Figure 1. Icon buttons, some of which are filled (indicating selection) and outlined.

API surface

Use the IconButton composable to implement standard icon buttons. To create different visual styles like filled, filled tonal, or outlined, use FilledIconButton, FilledTonalIconButton, and OutlinedIconButton, respectively.

The key parameters for IconButton include:

Basic example: Toggle icon button

This example shows you how to implement a toggle icon button. A toggle icon button changes its appearance based on whether it's selected or unselected.

@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."
        )
    }
}

Key points about the code

Result

The following image shows the toggle icon button from the preceding snippet in its unselected state:

A favorite toggle icon button (a heart) in its unselected state (unfilled). [A favorite toggle icon button (a heart) in its unselected state (unfilled).] Figure 2. A "favorite" toggle icon button in its unselected state.

Advanced example: Repeated actions on press

This section demonstrates how to create icon buttons that continuously trigger an action while the user presses and holds them, rather than just triggering once per click.

@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,
        )
    }
}

Key points about the code

Next, use this MomentaryIconButton in an example. The following snippet demonstrates two icon buttons controlling a counter:

@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 }
        )
    }
}

Key points about the code

Result

The following video shows the UI with the icon buttons and the counter:

Figure 3. A counter UI with two icon buttons (plus and minus) that increment and decrement the counter.

Additional resources

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-07-21 UTC.

[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-07-21 UTC."],[],[]]

Web Proxy Viewer  |  New URL  |  Original Page