A scroll indicator that transitions to indicate that a scroll gesture is available to the user.
OneHandedGestureScalingLazyColumnSample
@Composable
fun OneHandedGestureScalingLazyColumnSample() {
val backDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
val onClick =
remember<() -> Unit> { { backDispatcherOwner?.onBackPressedDispatcher?.onBackPressed() } }
val slcState = rememberScalingLazyListState()
val buttonInteractionSource = remember { MutableInteractionSource() }
val slcInteractionSource = remember { MutableInteractionSource() }
ScreenScaffold(
scrollState = slcState,
edgeButton = {
EdgeButton(
onClick = onClick,
interactionSource = buttonInteractionSource,
modifier =
if (slcState.canScrollForward) {
Modifier
} else {
// Apply the one-handed gesture modifier only when the container cannot
// scroll further, ensuring the EdgeButton is fully visible and interactive
Modifier.oneHandedGesture(
action = GestureAction.Primary,
priority = GesturePriority.Clickable,
interactionSource = buttonInteractionSource,
onGesture = onClick,
)
} then
Modifier.scrollable(
state = slcState,
orientation = Orientation.Vertical,
reverseDirection = true,
overscrollEffect = rememberOverscrollEffect(),
),
) {
OneHandedGestureIndicator(interactionSource = buttonInteractionSource) {
Text("Close")
}
}
},
scrollIndicator = {
OneHandedGestureScrollIndicator(
interactionSource = slcInteractionSource,
state = slcState,
modifier = Modifier.align(Alignment.CenterEnd),
)
},
) { contentPadding ->
ScalingLazyColumn(
state = slcState,
contentPadding = contentPadding,
modifier =
Modifier.fillMaxSize()
.oneHandedGesture(
action = GestureAction.Primary,
priority = GesturePriority.Scrollable,
interactionSource = slcInteractionSource,
onGesture = { OneHandedGestureDefaults.scrollDown(slcState) },
),
autoCentering = null,
) {
items(10) { Text("Item $it") }
}
}
}
@Composable
fun OneHandedGestureTransformingLazyColumnSample() {
val backDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
val onClick =
remember<() -> Unit> { { backDispatcherOwner?.onBackPressedDispatcher?.onBackPressed() } }
val scrollState = rememberTransformingLazyColumnState()
val buttonInteractionSource = remember { MutableInteractionSource() }
val scrollInteractionSource = remember { MutableInteractionSource() }
ScreenScaffold(
scrollState = scrollState,
edgeButton = {
EdgeButton(
onClick = onClick,
interactionSource = buttonInteractionSource,
modifier =
if (scrollState.canScrollForward) {
Modifier
} else {
// Apply the one-handed gesture modifier only when the container cannot
// scroll further, ensuring the EdgeButton is fully visible and interactive
Modifier.oneHandedGesture(
action = GestureAction.Primary,
priority = GesturePriority.Clickable,
interactionSource = buttonInteractionSource,
onGesture = onClick,
)
} then
Modifier.scrollable(
state = scrollState,
orientation = Orientation.Vertical,
reverseDirection = true,
overscrollEffect = rememberOverscrollEffect(),
),
) {
OneHandedGestureIndicator(interactionSource = buttonInteractionSource) {
Text("Close")
}
}
},
scrollIndicator = {
OneHandedGestureScrollIndicator(
interactionSource = scrollInteractionSource,
state = scrollState,
modifier = Modifier.align(Alignment.CenterEnd),
)
},
) { contentPadding ->
TransformingLazyColumn(
state = scrollState,
contentPadding = contentPadding,
modifier =
Modifier.fillMaxSize()
.oneHandedGesture(
action = GestureAction.Primary,
priority = GesturePriority.Scrollable,
interactionSource = scrollInteractionSource,
onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) },
),
) {
items(10) { Text("Item $it") }
}
}
}