0

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.

Hawklike
  • 952
  • 16
  • 23

1 Answers1

1

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
            )
Jorn
  • 20,612
  • 18
  • 79
  • 126
  • The initial value of the `sizePx` cannot be 0, because the initial value of the `swipeableState` must have an associated anchor. However, when setting the `sizePx` to another value, for example, 1, it works. – Hawklike Aug 21 '23 at 15:02