OneHandedGestureDefaults

object OneHandedGestureDefaults


Summary

Public functions

suspend Unit

A scroll implementation tailored for use with TransformingLazyColumnState.

suspend Unit

Automatically animates the pagerState to the next available page.

Public functions

scrollDown

Added in 1.7.0-alpha03
suspend fun scrollDown(scrollState: TransformingLazyColumnState): Unit

A scroll implementation tailored for use with TransformingLazyColumnState.

This logic handles one-handed gesture by first attempting to scroll to the next item in the list (or scrolling through the current item if it exceeds the viewport size). If the list cannot scroll further forward, it scrolls back to the start.

Sample demonstrating gesture handling with TransformingLazyColumnState:

import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.rememberOverscrollEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.onehandedgesture.GestureAction
import androidx.wear.compose.material3.onehandedgesture.GesturePriority
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureDefaults
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureIndicator
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureScrollIndicator
import androidx.wear.compose.material3.onehandedgesture.oneHandedGesture

val backDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
val onClick =
    remember<() -> Unit> { { backDispatcherOwner?.onBackPressedDispatcher?.onBackPressed() } }
val tlcState = rememberTransformingLazyColumnState()
var scrollGestureIndicatorVisible by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }

ScreenScaffold(
    scrollState = tlcState,
    edgeButton = {
        var buttonGestureIndicatorVisible by remember { mutableStateOf(false) }
        EdgeButton(
            onClick = onClick,
            interactionSource = interactionSource,
            modifier =
                if (tlcState.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 = interactionSource,
                        onShowIndicator = { buttonGestureIndicatorVisible = true },
                        onGesture = onClick,
                    )
                } then
                    Modifier.scrollable(
                        tlcState,
                        orientation = Orientation.Vertical,
                        reverseDirection = true,
                        overscrollEffect = rememberOverscrollEffect(),
                    ),
        ) {
            OneHandedGestureIndicator(
                buttonGestureIndicatorVisible,
                { buttonGestureIndicatorVisible = false },
            ) {
                Text("Close")
            }
        }
    },
    scrollIndicator = {
        OneHandedGestureScrollIndicator(
            scrollGestureIndicatorVisible,
            onGestureIndicatorFinished = { scrollGestureIndicatorVisible = false },
            tlcState,
            modifier = Modifier.align(Alignment.CenterEnd),
        )
    },
) { contentPadding ->
    TransformingLazyColumn(
        state = tlcState,
        contentPadding = contentPadding,
        modifier =
            Modifier.fillMaxSize()
                .oneHandedGesture(
                    action = GestureAction.Primary,
                    priority = GesturePriority.Scrollable,
                    onGesture = { OneHandedGestureDefaults.scrollDown(tlcState) },
                    onShowIndicator = { scrollGestureIndicatorVisible = true },
                ),
    ) {
        items(10) { Text("Item $it") }
    }
}
Parameters
scrollState: TransformingLazyColumnState

The scroll state associated with a transforming lazy column.

scrollToNextPage

Added in 1.7.0-alpha03
suspend fun scrollToNextPage(pagerState: PagerState): Unit

Automatically animates the pagerState to the next available page.

This function triggers a smooth scroll transition to the next page index. If the current page is the last page in the pager, the animation will wrap around to the first page (index 0).

Samples demonstrating gesture handling with horizontal and vertical pagers:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.pager.HorizontalPager
import androidx.wear.compose.foundation.pager.rememberPagerState
import androidx.wear.compose.material3.AnimatedPage
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.onehandedgesture.GestureAction
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureDefaults
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureHorizontalPageIndicator
import androidx.wear.compose.material3.onehandedgesture.oneHandedGesture

val pagerState = rememberPagerState(pageCount = { 10 })
var pageGestureIndicatorVisible by remember { mutableStateOf(false) }

HorizontalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureHorizontalPageIndicator(
            pagerState = pagerState,
            gestureIndicatorVisible = pageGestureIndicatorVisible,
            onGestureIndicatorFinished = { pageGestureIndicatorVisible = false },
        )
    },
) {
    HorizontalPager(
        state = pagerState,
        modifier =
            Modifier.oneHandedGesture(
                action = GestureAction.Primary,
                onShowIndicator = { pageGestureIndicatorVisible = true },
            ) {
                OneHandedGestureDefaults.scrollToNextPage(pagerState)
            },
    ) { page ->
        AnimatedPage(pageIndex = page, pagerState = pagerState) {
            ScreenScaffold {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    Text(text = "Page #$page")
                    Spacer(modifier = Modifier.height(8.dp))
                    Text(text = "Swipe left and right")
                }
            }
        }
    }
}
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.pager.VerticalPager
import androidx.wear.compose.foundation.pager.rememberPagerState
import androidx.wear.compose.material3.AnimatedPage
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.Text
import androidx.wear.compose.material3.VerticalPagerScaffold
import androidx.wear.compose.material3.onehandedgesture.GestureAction
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureDefaults
import androidx.wear.compose.material3.onehandedgesture.OneHandedGestureVerticalPageIndicator
import androidx.wear.compose.material3.onehandedgesture.oneHandedGesture

val pagerState = rememberPagerState(pageCount = { 10 })
var pageGestureIndicatorVisible by remember { mutableStateOf(false) }

VerticalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureVerticalPageIndicator(
            pagerState = pagerState,
            gestureIndicatorVisible = pageGestureIndicatorVisible,
            onGestureIndicatorFinished = { pageGestureIndicatorVisible = false },
        )
    },
) {
    VerticalPager(
        state = pagerState,
        modifier =
            Modifier.oneHandedGesture(
                action = GestureAction.Primary,
                onShowIndicator = { pageGestureIndicatorVisible = true },
            ) {
                OneHandedGestureDefaults.scrollToNextPage(pagerState)
            },
    ) { page ->
        AnimatedPage(pageIndex = page, pagerState = pagerState) {
            ScreenScaffold {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center,
                ) {
                    Text(text = "Page #$page")
                    Spacer(modifier = Modifier.height(8.dp))
                    Text(text = "Swipe up and down")
                }
            }
        }
    }
}
Parameters
pagerState: PagerState

The state of the pager to be animated.