As all cute workarounds go, <@U4XJ7P37S> your Rota...
# compose-wear
y
As all cute workarounds go, @saryong your Rotary Event Handler will break in Compose 1.1.0-beta04. cc @John O'Reilly
👍 2
I'm not 100% certain it's the same as this, but seems likely https://kotlinlang.slack.com/archives/CJLTWPH7S/p1638894543231800
Which mentions https://issuetracker.google.com/issues/202569585, so hopefully temporary and fixed in beta05, 06?
@saryong question for you, should this be a DisposableEffect? If you go to another page which doesn't hook up a new RotaryEventState, it seems like it may keep scrolling the one offscreen?
Copy code
fun RotaryEventState(scrollState: ScrollableState?) {
    val dispatcher = LocalRotaryEventDispatcher.current
    SideEffect {
        dispatcher.scrollState = scrollState
    }
}
j
@Sergio Sancho Can you chime in here?
b
I also encountered the same situation. In my case, when i update wear compose version to 1.0.0-alpha11 to 1.0.0-alpha12, rotary control is not working. However, scroll with scalingLazyColumn is normal. So, I try to change these logic to document's way but example code have so many deprecated function.(https://developer.android.com/training/wearables/user-input/rotary-input)
s
@yschimke oh, very nice catch. I must be
DisposableEffect
like you said. 🙂
y
@barat I'm sure @John Nichol will hate me for mentioning this, but until it's fixed I've been pinning to compose 1.1.0-beta03, it seems to work with wear compose alpha11, but there is no guarantee it doesn't hit some awful internal API change, hopefully reasonable safe since beta03 -> beta04 shouldn't have public API changes.
Copy code
allprojects {
    configurations.all {
        resolutionStrategy.eachDependency {
            if (requested.group.startsWith("androidx.compose.") && requested.version == "1.1.0-beta04") {
                useVersion("1.1.0-beta03")
                because("fixes scrolling bug")
            }
        }
    }
}
b
yeah i agree with that. I hold this version, and when I update the later version, I plan to run more close inspections on my functions.
y
@saryong I ended up with the following since it's in a HorizontalPager and the items are eagerly composed. So LaunchedEffect and friends don't trigger at the right times. So no issue with the DisposableAffect. Looking forward to native support in Wear Compose, should simplify this a lot.
Copy code
LaunchedEffect(key1 = pagerState.currentPage) {
                            when (pagerState.currentPage) {
                                0 -> rotaryEventDispatcher.scrollState = volumeScrollableState
                                1 -> rotaryEventDispatcher.scrollState = libraryScrollState
                            }
                        }
As a temporary workaround since I wanted to upgrade a personal app to 1.6.10 and remove the pin on beta03, I've used the following to workaround. Very happy to delete once it's built into Wear Compose.
Copy code
ScalingLazyColumn(
        modifier = modifier.scrollHandler(scrollState),
Copy code
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.scrollHandler(scrollState: ScrollableState): Modifier = composed {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    val scaledVerticalScrollFactor =
        remember { ViewConfiguration.get(context).getScaledVerticalScrollFactor() }

    this.pointerInteropFilter(RequestDisallowInterceptTouchEvent()) { event ->
        if (event.action != MotionEvent.ACTION_SCROLL ||
            !event.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
        ) {
            false
        } else {
            val delta = -event.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
                    scaledVerticalScrollFactor
            scope.launch {
                scrollState.scrollBy(delta)
            }
            true
        }
    }
}
👍 2
b
Thanks. Yuri. Your code work like charm.
👍🏻 1