OneHandedGestureDefaults

object OneHandedGestureDefaults


Contains the default values used by one-handed gestures

Summary

Public functions

Unit
@Composable
GestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    modifier: Modifier,
    content: @Composable () -> Unit
)

A wrapper that replaces the content to indicate to the user that a gesture action is available.

Unit
@Composable
HorizontalPageGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    pagerState: PagerState,
    modifier: Modifier,
    selectedColor: Color,
    unselectedColor: Color,
    backgroundColor: Color
)

A horizontal page indicator that can temporarily display a gesture indicator to demonstrate how to navigate between pages using one-handed gestures.

Unit
@Composable
ScrollGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    state: TransformingLazyColumnState,
    modifier: Modifier,
    colors: ScrollIndicatorColors,
    reverseDirection: Boolean,
    positionAnimationSpec: AnimationSpec<Float>
)

A scroll indicator that transitions to indicate that a scroll gesture is available to the user.

Unit
@Composable
VerticalPageGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    pagerState: PagerState,
    modifier: Modifier,
    selectedColor: Color,
    unselectedColor: Color,
    backgroundColor: Color
)

A vertical page indicator that can temporarily display a gesture indicator to demonstrate how to navigate between pages using one-handed gestures.

suspend Unit

A scroll implementation tailored for use with TransformingLazyColumnState.

suspend Unit

Automatically animates the pagerState to the next available page.

Public properties

Dp

The recommended default size for indicators when used inside a content of size 48dp or greater

Dp

The recommended default size for indicators when used inside a content of size less than 48dp

Public functions

GestureIndicator

Added in 1.7.0-alpha01
@Composable
fun GestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
): Unit

A wrapper that replaces the content to indicate to the user that a gesture action is available.

This component handles the visual transition between the standard content and a gesture indicator. When gestureIndicatorVisible is enabled, the content is swapped out for the indicator. Once the indicator display sequence is complete, onGestureIndicatorFinished is called, allowing the UI to return to its original state.

Sample demonstrating a gesture indicator applied to a androidx.wear.compose.material3.Button:

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.wear.compose.material3.Button
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.oneHandedGesture

var label by remember { mutableStateOf("Gesturable Button") }
val onClick = remember { { label = "Clicked/Gestured" } }
var gestureIndicatorVisible by remember { mutableStateOf(false) }
val interactionSource = remember { MutableInteractionSource() }

Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
    Button(
        onClick = onClick,
        interactionSource = interactionSource,
        modifier =
            Modifier.oneHandedGesture(
                action = GestureAction.Primary,
                interactionSource = interactionSource,
                onShowIndicator = { gestureIndicatorVisible = true },
                onGesture = onClick,
            ),
    ) {
        OneHandedGestureDefaults.GestureIndicator(
            gestureIndicatorVisible,
            { gestureIndicatorVisible = false },
        ) {
            Text(label)
        }
    }
}
Parameters
gestureIndicatorVisible: Boolean

A boolean flag that triggers the transition from content to the indicator. While true, the content is hidden and the indicator is played.

onGestureIndicatorFinished: () -> Unit

A lambda function to be called when the gesture indicator animation sequence finishes. Implementation of this lambda must reset gestureIndicatorVisible to false in order to restore the original content.

modifier: Modifier = Modifier

The Modifier to be applied to the indicator animation container.

content: @Composable () -> Unit

The original button content (e.g., Text or Icon) to be displayed when no indicator is active.

HorizontalPageGestureIndicator

Added in 1.7.0-alpha01
@Composable
fun HorizontalPageGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    pagerState: PagerState,
    modifier: Modifier = Modifier,
    selectedColor: Color = PageIndicatorDefaults.selectedColor,
    unselectedColor: Color = PageIndicatorDefaults.unselectedColor,
    backgroundColor: Color = PageIndicatorDefaults.backgroundColor
): Unit

A horizontal page indicator that can temporarily display a gesture indicator to demonstrate how to navigate between pages using one-handed gestures.

In its idle state, this component functions as a standard page indicator, using dots or bars to represent the pagerState. When gestureIndicatorVisible is set to true, the indicator temporarily replaces its standard visual state with a gesture animation sequence.

Sample demonstrating a gesture indicator applied to a androidx.wear.compose.foundation.pager.HorizontalPager:

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.oneHandedGesture

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

HorizontalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureDefaults.HorizontalPageGestureIndicator(
            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")
                }
            }
        }
    }
}
Parameters
gestureIndicatorVisible: Boolean

A boolean flag that triggers the gesture indicator animation. While true, the standard scroll indicator is transformed into the gesture indicator.

onGestureIndicatorFinished: () -> Unit

A lambda function to be called when the gesture indicator animation sequence finishes. Implementation of this lambda must reset gestureIndicatorVisible to false in order to restore the original content.

pagerState: PagerState

The state of the androidx.wear.compose.foundation.pager.HorizontalPager that this indicator represents.

modifier: Modifier = Modifier

Modifier to be applied to the HorizontalPageIndicator

selectedColor: Color = PageIndicatorDefaults.selectedColor

The color which will be used for a selected indicator item.

unselectedColor: Color = PageIndicatorDefaults.unselectedColor

The color which will be used for an unselected indicator item.

backgroundColor: Color = PageIndicatorDefaults.backgroundColor

The color which will be used for an indicator background.

ScrollGestureIndicator

Added in 1.7.0-alpha01
@Composable
fun ScrollGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    state: TransformingLazyColumnState,
    modifier: Modifier = Modifier,
    colors: ScrollIndicatorColors = ScrollIndicatorDefaults.colors(),
    reverseDirection: Boolean = false,
    positionAnimationSpec: AnimationSpec<Float> = ScrollIndicatorDefaults.PositionAnimationSpec
): Unit

A scroll indicator that transitions to indicate that a scroll gesture is available to the user.

Under normal conditions, this component behaves like a standard scroll indicator, reflecting the current scroll position of a androidx.wear.compose.foundation.lazy.TransformingLazyColumn. When gestureIndicatorVisible is set to true, the indicator temporarily replaces its standard visual state with a gesture animation sequence.

Sample demonstrating a gesture indicator applied to a androidx.wear.compose.foundation.lazy.TransformingLazyColumn:

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.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(),
                    ),
        ) {
            OneHandedGestureDefaults.GestureIndicator(
                buttonGestureIndicatorVisible,
                { buttonGestureIndicatorVisible = false },
            ) {
                Text("Close")
            }
        }
    },
    scrollIndicator = {
        OneHandedGestureDefaults.ScrollGestureIndicator(
            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
gestureIndicatorVisible: Boolean

A boolean flag that triggers the gesture indicator animation. While true, the standard scroll indicator is transformed into the gesture indicator.

onGestureIndicatorFinished: () -> Unit

A lambda function to be called when the gesture indicator animation sequence finishes. Implementation of this lambda must reset gestureIndicatorVisible to false in order to restore the original content.

state: TransformingLazyColumnState

The state object of the androidx.wear.compose.foundation.lazy.TransformingLazyColumn this indicator is coupled with.

modifier: Modifier = Modifier

The Modifier to be applied to the scroll indicator.

colors: ScrollIndicatorColors = ScrollIndicatorDefaults.colors()

ScrollIndicatorColors that will be used to resolve the indicator and track colors for this androidx.wear.compose.material3.ScrollIndicator.

reverseDirection: Boolean = false

Reverses direction of ScrollIndicator if true.

positionAnimationSpec: AnimationSpec<Float> = ScrollIndicatorDefaults.PositionAnimationSpec

AnimationSpec for position animation. The Position animation is used for animating changes to the scroll size and position. To disable this animation androidx.compose.animation.core.snap AnimationSpec should be passed instead.

VerticalPageGestureIndicator

Added in 1.7.0-alpha01
@Composable
fun VerticalPageGestureIndicator(
    gestureIndicatorVisible: Boolean,
    onGestureIndicatorFinished: () -> Unit,
    pagerState: PagerState,
    modifier: Modifier = Modifier,
    selectedColor: Color = PageIndicatorDefaults.selectedColor,
    unselectedColor: Color = PageIndicatorDefaults.unselectedColor,
    backgroundColor: Color = PageIndicatorDefaults.backgroundColor
): Unit

A vertical page indicator that can temporarily display a gesture indicator to demonstrate how to navigate between pages using one-handed gestures.

In its idle state, this component functions as a standard page indicator, using dots or bars to represent the pagerState. When gestureIndicatorVisible is set to true, the indicator temporarily replaces its standard visual state with a gesture animation sequence.

Sample demonstrating a gesture indicator applied to a androidx.wear.compose.foundation.pager.VerticalPager:

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.oneHandedGesture

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

VerticalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureDefaults.VerticalPageGestureIndicator(
            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
gestureIndicatorVisible: Boolean

A boolean flag that triggers the gesture indicator animation. While true, the standard scroll indicator is transformed into the gesture indicator.

onGestureIndicatorFinished: () -> Unit

A lambda function to be called when the gesture indicator animation sequence finishes. Implementation of this lambda must reset gestureIndicatorVisible to false in order to restore the original content.

pagerState: PagerState

The state of the androidx.wear.compose.foundation.pager.VerticalPager that this indicator represents.

modifier: Modifier = Modifier

Modifier to be applied to the VerticalPageIndicator

selectedColor: Color = PageIndicatorDefaults.selectedColor

The color which will be used for a selected indicator item.

unselectedColor: Color = PageIndicatorDefaults.unselectedColor

The color which will be used for an unselected indicator item.

backgroundColor: Color = PageIndicatorDefaults.backgroundColor

The color which will be used for an indicator background.

scrollDown

Added in 1.7.0-alpha01
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.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(),
                    ),
        ) {
            OneHandedGestureDefaults.GestureIndicator(
                buttonGestureIndicatorVisible,
                { buttonGestureIndicatorVisible = false },
            ) {
                Text("Close")
            }
        }
    },
    scrollIndicator = {
        OneHandedGestureDefaults.ScrollGestureIndicator(
            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-alpha01
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.oneHandedGesture

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

HorizontalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureDefaults.HorizontalPageGestureIndicator(
            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.oneHandedGesture

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

VerticalPagerScaffold(
    pagerState = pagerState,
    pageIndicator = {
        OneHandedGestureDefaults.VerticalPageGestureIndicator(
            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.

Public properties

GestureIndicatorSize

val GestureIndicatorSizeDp

The recommended default size for indicators when used inside a content of size 48dp or greater

GestureIndicatorSmallSize

val GestureIndicatorSmallSizeDp

The recommended default size for indicators when used inside a content of size less than 48dp