Jetpack Compose: swipeable anchors depend on the on size of the component

480 Views Asked by At

The documentation provides a sample of the swipeable modifier. However, the sample defines anchors with hardcoded values.

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun SwipeableSample() {
    val width = 96.dp
    val squareSize = 48.dp

    val swipeableState = rememberSwipeableState(0)
    val sizePx = with(LocalDensity.current) { squareSize.toPx() }
    val anchors = mapOf(0f to 0, sizePx to 1) // Maps anchor points (in px) to states

    Box(
        modifier = Modifier
            .width(width)
            .swipeable(
                state = swipeableState,
                anchors = anchors,
                thresholds = { _, _ -> FractionalThreshold(0.3f) },
                orientation = Orientation.Horizontal
            )
            .background(Color.LightGray)
    ) {
        ...
    }
}

How to define anchors that depend on the size of a component?

I know AnchoredDraggable should provide a straightforward solution, but it is still in alpha.

1

There are 1 best solutions below

1
On

Turn the sizePx value into a State object. Then you can save the actual width:

var sizePx by remember { mutableStateOf(0) }
Modifier.onGloballyPositioned { sizePx = it.size.width /* and/or update anchors */ }
            .swipeable(
                state = swipeableState,
                anchors = anchors,
                thresholds = { _, _ -> FractionalThreshold(0.3f) },
                orientation = Orientation.Horizontal
            )