# androidx.compose.ui.input.rotary

Common/AllAndroid/JVM

## Interfaces

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryInputModifierNode` | Implement this interface to create a `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.Node` that can intercept rotary scroll events. | Cmn |

## Classes

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent` | This event represents a rotary input event. | Cmn android |

## Extension functions summary

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onPreRotaryScrollEvent(kotlin.Function1)( onPreRotaryScrollEvent: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Adding this `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` to the `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` parameter of a component will allow it to intercept `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`s if it (or one of its children) is focused. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onRotaryScrollEvent(kotlin.Function1)( onRotaryScrollEvent: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html )` Adding this `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` to the `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` parameter of a component will allow it to intercept `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`s if it (or one of its children) is focused. | Cmn |

## Extension functions

### onPreRotaryScrollEvent

Cmn Artifact: [androidx.compose.ui:ui](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/input/rotary/RotaryInputModifier.kt+function:onPreRotaryScrollEvent) Added in [1.2.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.2.0)

```
fun Modifier.onPreRotaryScrollEvent(
    onPreRotaryScrollEvent: (RotaryScrollEvent) -> Boolean
): Modifier
```

Adding this `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` to the `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` parameter of a component will allow it to intercept `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`s if it (or one of its children) is focused.

```kotlin
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.darkColors
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.input.rotary.onPreRotaryScrollEvent
import androidx.compose.ui.input.rotary.onRotaryScrollEvent
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp

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() }
}
```

| Parameters |
|---|---|
| `onPreRotaryScrollEvent: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | This callback is invoked when the user interacts with the rotary button on a wear device. It gives ancestors of a focused component the chance to intercept a `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`. When the user rotates the side button on a wear device, a `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent` is sent to the focused item. Before reaching the focused item, this event starts at the root composable, and propagates down the hierarchy towards the focused item. It invokes any `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onPreRotaryScrollEvent(kotlin.Function1)`s it encounters on ancestors of the focused item. After reaching the focused item, the event propagates up the hierarchy back towards the parent. It invokes any `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onRotaryScrollEvent(kotlin.Function1)`s it encounters on its way back. Return true to indicate that you consumed the event and want to stop propagation of this event. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` | true if the event is consumed, false otherwise. |

### onRotaryScrollEvent

Cmn Artifact: [androidx.compose.ui:ui](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/input/rotary/RotaryInputModifier.kt+function:onRotaryScrollEvent) Added in [1.2.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.2.0)

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

Adding this `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` to the `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` parameter of a component will allow it to intercept `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`s if it (or one of its children) is focused.

```kotlin
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.input.rotary.onRotaryScrollEvent

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() }
```

This sample demonstrates how a parent can add an `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onRotaryScrollEvent(kotlin.Function1)` modifier to gain access to a `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent` when a child does not consume it:

```kotlin
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.darkColors
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.input.rotary.onPreRotaryScrollEvent
import androidx.compose.ui.input.rotary.onRotaryScrollEvent
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp

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() }
}
```

| Parameters |
|---|---|
| `onRotaryScrollEvent: (https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | This 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 `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/package-summary#(androidx.compose.ui.Modifier).onRotaryScrollEvent(kotlin.Function1)`'s parent. |

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier` | true if the event is consumed, false otherwise. Here is an example of a scrollable container that scrolls in response to `https://developer.android.com/reference/kotlin/androidx/compose/ui/input/rotary/RotaryScrollEvent`s. |