Build apps faster with our new App builder! 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.

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-alpha34")
}

Overloads

@Composable
@Suppress("ComposableLambdaParameterPosition")
fun PickerGroup(
    modifier: Modifier = Modifier,
    selectedPickerState: PickerState? = null,
    autoCenter: Boolean = true,
    propagateMinConstraints: Boolean = false,
    content: @Composable PickerGroupScope.() -> Unit
)

Parameters

namedescription
selectedPickerStateThe [PickerState] of the [Picker] that is selected. Null value means that no [Picker] is selected.
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.
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))
        val label = if (selectedPickerIndex == 0) "Hours" else "Minutes"
        AnimatedContent(
            targetState = label,
        ) { targetText ->
            Text(text = targetText)
        }
        Spacer(modifier = Modifier.size(10.dp))
        PickerGroup(
            selectedPickerState =
                if (selectedPickerIndex == 0) pickerStateHour else pickerStateMinute,
            autoCenter = false
        ) {
            PickerGroupItem(
                pickerState = pickerStateHour,
                selected = selectedPickerIndex == 0,
                onSelected = { selectedPickerIndex = 0 },
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )

            PickerGroupItem(
                pickerState = pickerStateMinute,
                selected = selectedPickerIndex == 1,
                onSelected = { selectedPickerIndex = 1 },
                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)
    val pickerStates = remember {
        arrayOf(pickerStateHour, pickerStateMinute, pickerStateSeconds, pickerStateMilliSeconds)
    }

    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))
        AnimatedContent(targetState = headingText[selectedPickerIndex]!!) { targetText ->
            Text(text = targetText)
        }
        Spacer(modifier = Modifier.size(10.dp))
        PickerGroup(selectedPickerState = pickerStates[selectedPickerIndex], autoCenter = true) {
            PickerGroupItem(
                pickerState = pickerStateHour,
                selected = selectedPickerIndex == 0,
                onSelected = { selectedPickerIndex = 0 },
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            PickerGroupItem(
                pickerState = pickerStateMinute,
                selected = selectedPickerIndex == 1,
                onSelected = { selectedPickerIndex = 1 },
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            PickerGroupItem(
                pickerState = pickerStateSeconds,
                selected = selectedPickerIndex == 2,
                onSelected = { selectedPickerIndex = 2 },
                option = { optionIndex, _ -> Text(text = "%02d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
            PickerGroupItem(
                pickerState = pickerStateMilliSeconds,
                selected = selectedPickerIndex == 3,
                onSelected = { selectedPickerIndex = 3 },
                option = { optionIndex, _ -> Text(text = "%03d".format(optionIndex)) },
                modifier = Modifier.size(80.dp, 100.dp)
            )
        }
    }
}
by @alexstyl