New Compose Multiplatform components arrived on Composables UICheck it out →

Modifier in Compose Ui

onRotaryScrollEvent

Common

Adding this [modifier][Modifier] to the [modifier][Modifier] parameter of a component will allow it to intercept [RotaryScrollEvent]s if it (or one of its children) is focused.

Last updated:

Installation

dependencies {
   implementation("androidx.compose.ui:ui:1.7.0-beta04")
}

Overloads


fun Modifier.onRotaryScrollEvent(
    onRotaryScrollEvent: (RotaryScrollEvent) -> Boolean
)

Parameters

namedescription
onRotaryScrollEventThis callback is invoked when the user interacts with the rotary side button or the bezel on a wear device. While implementing this callback, return true to stop propagation of this event. If you return false, the event will be sent to this [onRotaryScrollEvent]'s parent.

Code Examples

RotaryEventSample

@Composable
@Sampled
@OptIn(ExperimentalComposeUiApi::class
fun RotaryEventSample() {
    val scrollState = rememberScrollState()
    val coroutineScope = rememberCoroutineScope()
    val focusRequester = remember { FocusRequester() }
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .verticalScroll(scrollState)
            .onRotaryScrollEvent {
                coroutineScope.launch {
                    scrollState.scrollTo((scrollState.value +
                        it.verticalScrollPixels).roundToInt())
                }
                true
            }
            .focusRequester(focusRequester)
            .focusable(),
    ) {
        repeat(100) {
            Text(
                text = "item $it",
                modifier = Modifier.align(CenterHorizontally),
                color = White,
            )
        }
    }

    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }
}

PreRotaryEventSample

@Composable
@Sampled
@OptIn(ExperimentalComposeUiApi::class
fun PreRotaryEventSample() {
    MaterialTheme(colors = darkColors()) {
        val rowScrollState = rememberScrollState()
        val columnScrollState = rememberScrollState()
        val coroutineScope = rememberCoroutineScope()
        val focusRequester = remember { FocusRequester() }
        var interceptScroll by remember { mutableStateOf(false) }
        Column(
            Modifier
                .onPreRotaryScrollEvent {
                    // You can intercept an event before it is sent to the child.
                    if (interceptScroll) {
                        coroutineScope.launch {
                            rowScrollState.scrollBy(it.horizontalScrollPixels)
                        }
                        // return true to consume this event.
                        true
                    } else {
                        // return false to ignore this event and continue propagation to the child.
                        false
                    }
                }
                .onRotaryScrollEvent {
                    // If the child does not use the scroll, we get notified here.
                    coroutineScope.launch {
                        rowScrollState.scrollBy(it.horizontalScrollPixels)
                    }
                    true
                }
        ) {
            Row(
                modifier = Modifier.align(CenterHorizontally),
                verticalAlignment = CenterVertically
            ) {
                Text(
                    modifier = Modifier.width(70.dp),
                    text = if (interceptScroll) "Row" else "Column",
                    style = TextStyle(color = White)
                )
                Switch(
                    checked = interceptScroll,
                    onCheckedChange = { interceptScroll = it },
                )
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .horizontalScroll(rowScrollState)
            ) {
                repeat(100) {
                    Text(
                        text = "row item $it ",
                        modifier = Modifier.align(CenterVertically),
                        color = White,
                    )
                }
            }
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .verticalScroll(columnScrollState)
                    .onRotaryScrollEvent {
                        coroutineScope.launch {
                            columnScrollState.scrollBy(it.verticalScrollPixels)
                        }
                        true
                    }
                    .focusRequester(focusRequester)
                    .focusable(),
            ) {
                repeat(100) {
                    Text(
                        text = "column item $it",
                        modifier = Modifier.align(CenterHorizontally),
                        color = White,
                    )
                }
            }
        }

        LaunchedEffect(Unit) {
            focusRequester.requestFocus()
        }
    }
}