We just launched Compose Examples featuring over 150+ components! Check it out →

PickerGroup

Android

Component in Wear Material 3 Compose

A group of [Picker]s to build components where multiple pickers are required to be combined together. At most one [Picker] can be selected at a time. When touch exploration services are enabled, the focus moves to the picker which is clicked. To handle clicks in a different manner, use the [onPickerSelected] lambda to control the focus of talkback and actual focus.

It is recommended to ensure that a [Picker] in non read only mode should have user scroll enabled when touch exploration services are running.

Last updated:

Installation

dependencies {
   implementation("androidx.wear.compose:compose-material3:1.0.0-alpha27")
}

Overloads

@Composable
@Suppress("ComposableLambdaParameterPosition")
fun PickerGroup(
    selectedPickerIndex: Int,
    onPickerSelected: (selectedIndex: Int) -> Unit,
    modifier: Modifier = Modifier,
    autoCenter: Boolean = true,
    separator: (@Composable (Int) -> Unit)? = null,
    propagateMinConstraints: Boolean = false,
    content: PickerGroupScope.() -> Unit
)

Parameters

namedescription
selectedPickerIndexThe index of the [Picker] that is selected. The value is ignored when negative, which means that no [Picker] is selected.
onPickerSelectedAction triggered when one of the [Picker]s is selected inside the group. Typically, [selectedPickerIndex] and [onPickerSelected] are used in tandem to apply a visual highlight to the currently selected [Picker] as a guide to the user.
modifier[Modifier] to be applied to the [PickerGroup].
autoCenterIndicates whether the selected [Picker] should be centered on the screen. It is recommended to set this as true when all the pickers cannot be fit into the screen. Or provide a mechanism to navigate to pickers which are not visible on screen. If false, the whole row containing pickers would be centered.
propagateMinConstraintsWhether the incoming min constraints should be passed to content.
separatorA composable block which describes the separator between different [Picker]s. The integer parameter to the composable depicts the index where it will be kept. For example, 0 would represent the separator between the first and second picker.
contentThe content of the [PickerGroup] as a container of [Picker]s.

Code Examples

PickerGroupSample

@Composable
fun PickerGroupSample() {
    var selectedPickerIndex by remember { mutableIntStateOf(0) }
    val pickerStateHour = rememberPickerState(initialNumberOfOptions = 24)
    val pickerStateMinute = rememberPickerState(initialNumberOfOptions = 60)
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Spacer(modifier = Modifier.size(30.dp))
        Text(text = if (selectedPickerIndex == 0) "Hours" else "Minutes")
        Spacer(modifier = Modifier.size(10.dp))
        PickerGroup(
            selectedPickerIndex = selectedPickerIndex,
            onPickerSelected = { selectedPickerIndex = it },
            autoCenter = false
        ) {
            pickerGroupItem(
                pickerState = pickerStateHour,
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            pickerGroupItem(
                pickerState = pickerStateMinute,
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
        }
    }
}

AutoCenteringPickerGroup

@Composable
fun AutoCenteringPickerGroup() {
    var selectedPickerIndex by remember { mutableIntStateOf(0) }
    val pickerStateHour = rememberPickerState(initialNumberOfOptions = 24)
    val pickerStateMinute = rememberPickerState(initialNumberOfOptions = 60)
    val pickerStateSeconds = rememberPickerState(initialNumberOfOptions = 60)
    val pickerStateMilliSeconds = rememberPickerState(initialNumberOfOptions = 1000)
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        val headingText = mapOf(0 to "Hours", 1 to "Minutes", 2 to "Seconds", 3 to "Milli")
        Spacer(modifier = Modifier.size(30.dp))
        Text(text = headingText[selectedPickerIndex]!!)
        Spacer(modifier = Modifier.size(10.dp))
        PickerGroup(
            selectedPickerIndex = selectedPickerIndex,
            onPickerSelected = { selectedPickerIndex = it },
            autoCenter = true
        ) {
            pickerGroupItem(
                pickerState = pickerStateHour,
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            pickerGroupItem(
                pickerState = pickerStateMinute,
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            pickerGroupItem(
                pickerState = pickerStateSeconds,
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            pickerGroupItem(
                pickerState = pickerStateMilliSeconds,
                option = { optionIndex, _ -> Text(text = "%03d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
        }
    }
}
by @alexstyl