ButtonGroup

Functions summary

Unit
@Composable
ButtonGroup(
    modifier: Modifier,
    spacing: Dp,
    expansionWidth: Dp,
    contentPadding: PaddingValues,
    verticalAlignment: Alignment.Vertical,
    transformation: SurfaceTransformation?,
    content: @Composable ButtonGroupScope.() -> Unit
)

Layout component to implement an expressive group of buttons in a row, that react to touch by growing the touched button, (while the neighbor(s) shrink to accommodate and keep the group width constant).

Functions

@Composable
fun ButtonGroup(
    modifier: Modifier = Modifier,
    spacing: Dp = ButtonGroupDefaults.Spacing,
    expansionWidth: Dp = ButtonGroupDefaults.ExpansionWidth,
    contentPadding: PaddingValues = ButtonGroupDefaults.fullWidthPaddings(),
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    transformation: SurfaceTransformation? = null,
    content: @Composable ButtonGroupScope.() -> Unit
): Unit

Layout component to implement an expressive group of buttons in a row, that react to touch by growing the touched button, (while the neighbor(s) shrink to accommodate and keep the group width constant).

Example of a ButtonGroup:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.ButtonGroup
import androidx.wear.compose.material3.Text

val interactionSource1 = remember { MutableInteractionSource() }
val interactionSource2 = remember { MutableInteractionSource() }

Box(contentAlignment = Alignment.Center) {
    ButtonGroup(Modifier.fillMaxWidth()) {
        Button(
            onClick = {},
            modifier = Modifier.animateWidth(interactionSource1),
            interactionSource = interactionSource1,
        ) {
            Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Text("L") }
        }
        Button(
            onClick = {},
            modifier = Modifier.animateWidth(interactionSource2),
            interactionSource = interactionSource2,
        ) {
            Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Text("R") }
        }
    }
}

Example of 3 buttons, the middle one bigger ButtonGroup:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.ButtonGroup
import androidx.wear.compose.material3.Text

val interactionSource1 = remember { MutableInteractionSource() }
val interactionSource2 = remember { MutableInteractionSource() }
val interactionSource3 = remember { MutableInteractionSource() }

var rtl by remember { mutableStateOf(false) }
Box(Modifier.fillMaxSize()) {
    CompositionLocalProvider(
        LocalLayoutDirection provides if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr
    ) {
        ButtonGroup(Modifier.fillMaxWidth().align(Alignment.Center)) {
            Button(
                onClick = {},
                modifier = Modifier.animateWidth(interactionSource1),
                interactionSource = interactionSource1,
            ) {
                Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Text("A") }
            }
            Button(
                onClick = {},
                modifier = Modifier.weight(1.5f).animateWidth(interactionSource2),
                interactionSource = interactionSource2,
            ) {
                Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Text("B") }
            }
            Button(
                onClick = {},
                modifier = Modifier.animateWidth(interactionSource3),
                interactionSource = interactionSource3,
            ) {
                Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Text("C") }
            }
        }
    }
    Button(modifier = Modifier.align(Alignment.BottomCenter), onClick = { rtl = !rtl }) {
        Text(if (rtl) "RTL" else "LTR")
    }
}
Parameters
modifier: Modifier = Modifier

Modifier to be applied to the button group

spacing: Dp = ButtonGroupDefaults.Spacing

the amount of spacing between buttons

expansionWidth: Dp = ButtonGroupDefaults.ExpansionWidth

how much buttons grow when pressed

contentPadding: PaddingValues = ButtonGroupDefaults.fullWidthPaddings()

The spacing values to apply internally between the container and the content

verticalAlignment: Alignment.Vertical = Alignment.CenterVertically

the vertical alignment of the button group's children.

transformation: SurfaceTransformation? = null

The transformation for the ButtonGroup when it's inside a dynamically changing container. To prevent a "double transformation" (on both the group and its buttons), individual Buttons inside this group must have their own container transformations disabled; only their content should be transformed.

content: @Composable ButtonGroupScope.() -> Unit

the content and properties of each button. The Ux guidance is to use no more than 3 buttons within a ButtonGroup. Note that this content is on the ButtonGroupScope, to provide access to 3 new modifiers to configure the buttons.