| **Warning:** This page and the snippets it contains are outdated.

[`Swipeable`](https://developer.android.com/reference/kotlin/androidx/compose/material/SwipeableState)is a Compose Material API that helps you build components that can be swiped between discrete states, such as bottom sheets, drawers, or swipe-to-dismiss. To better support advanced use cases, such as anchors that depend on the size of a component, a successor was published in Compose-Foundation 1.6.0-alpha01:[`AnchoredDraggable`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState).`AnchoredDraggable`is a Foundation API for building draggable components with anchored states, such as bottom sheets, drawers, or swipe-to-dismiss.

Material's`Swipeable`APIs have been deprecated in favor of Foundation's`AnchoredDraggable`and will be removed in a future release. This guide describes how to migrate from`Swipeable`APIs to`AnchoredDraggable`.
| **Note:** `AnchoredDraggable`is an experimental API. Experimental APIs may change in future.

## Migrate`SwipeableState`to`AnchoredDraggableState`

Start by identifying changes to your state holder.`AnchoredDraggableState`cannot be inherited from, and the offset is represented as`Float.NaN`before it is initialized.

### Update your state holder

[`AnchoredDraggableState`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState)is a final class, meaning it cannot be inherited from. If your existing component inherits from[`SwipeableState`](https://developer.android.com/reference/kotlin/androidx/compose/material/SwipeableState), update your state holder to hold a reference to the`AnchoredDraggableState`instead of inheriting from it:  

### Swipeable

    class MySwitchState: SwipeableState()

### AnchoredDraggable

    class MySwitchState {
        private val anchoredDraggableState = AnchoredDraggableState(...)
    }

Since your state holder does not inherit from`SwipeableState`anymore, you might have to expose APIs yourself. The most common APIs you can use are[`offset`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#offset()),[`progress`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#progress()),[`currentValue`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#currentValue())and[`targetValue`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#targetValue()).

### Access the offset

Unlike in`Swipeable`,`AnchoredDraggableState`'s`offset`is`Float.NaN`before it is initialized. In`AnchoredDraggable`, the anchors can be passed to`AnchoredDraggableState`'s constructor or updated through[`AnchoredDraggableState#updateAnchors`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#updateAnchors(androidx.compose.foundation.gestures.DraggableAnchors,kotlin.Any)). Passing the anchors to`AnchoredDraggableState`'s constructor initializes the offset immediately.

If your anchors depend on layout or could change, use`AnchoredDraggableState#updateAnchors`to avoid recreating the state when the anchors change.

If you use`updateAnchors`, the offset will be`Float.NaN`before passing the anchors to`updateAnchors`. To avoid accidentally passing`Float.NaN`to components, use[`AnchoredDraggableState#requireOffset`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/AnchoredDraggableState#requireOffset())to require that the offset has been initialized when reading it. This helps you catch inconsistencies or possible bugs early on.  

    @Composable
    fun AnchoredDraggableBox() {
        val state = remember { AnchoredDraggableState(...) }
        val density = LocalDensity.current
        val anchors = remember { DraggableAnchors { ... } }
        SideEffect {
            state.updateAnchors(anchors)
        }
        Box(
            Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
        }
    }

| **Note:** Overflow support for`AnchoredDraggable`is currently being implemented. See[b/288084801](https://issuetracker.google.com/288084801)for the latest status.

## Migrate`Modifier.swipeable`to`Modifier.anchoredDraggable`

[`Modifier.anchoredDraggable()`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/package-summary#(androidx.compose.ui.Modifier).anchoredDraggable(androidx.compose.foundation.gestures.AnchoredDraggableState,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource))replaces[`Modifier.swipeable`](https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#(androidx.compose.ui.Modifier).swipeable(androidx.compose.material.SwipeableState,kotlin.collections.Map,androidx.compose.foundation.gestures.Orientation,kotlin.Boolean,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function2,androidx.compose.material.ResistanceConfig,androidx.compose.ui.unit.Dp))(). Some of`Modifier.swipeable()`'s parameters have moved to`AnchoredDraggableState`directly, as described in the following sections.

### Define anchors

Define the anchors using the[`DraggableAnchors`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/DraggableAnchors)builder method. Then, pass them to`AnchoredDraggableState#updateAnchors`or`AnchoredDraggableState`'s constructor:  

### Constructor

    enum class DragValue { Start, Center, End }

    @Composable
    fun AnchoredDraggableBox() {
        val anchors = DraggableAnchors {
            Start at -100.dp.toPx()
            Center at 0f
            End at 100.dp.toPx()
        }
        val state = remember {
            AnchoredDraggableState(anchors = anchors)
        }
        Box(
            Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
        )
    }

### updateAnchors

    enum class DragValue { Start, Center, End }

    @Composable
    fun AnchoredDraggableBox() {
        val state = remember { AnchoredDraggableState(...) }
        val density = LocalDensity.current
        val anchors = with (density) {
            DraggableAnchors {
                Start at -100.dp.toPx()
                Center at 0f
                End at 100.dp.toPx()
            }
        }
        SideEffect {
            state.updateAnchors(anchors)
        }
        Box(
            Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
        )
    }

If the anchors are static, pass them to the constructor. If they depend on layout, or are not static, use`updateAnchors`.

### Define positional thresholds

The type and name of the thresholds parameter has changed. Instead of having a separate[`ThresholdConfig`](https://developer.android.com/reference/kotlin/androidx/compose/material/ThresholdConfig)interface,`AnchoredDraggableState`has a`positionalThreshold`parameter that takes a lambda function that returns the position of the threshold. For example, a positional threshold of 50% could be expressed as:  

    val anchoredDraggableState = AnchoredDraggableState(
        positionalThreshold = { distance -> distance * 0.5f },
        ...
    )

A positional threshold of`56dp`could be expressed as:  

    val density = LocalDensity.current
    val anchoredDraggableState = AnchoredDraggableState(
        positionalThreshold = { with(density) { 56.dp.toPx() } },
        ...
    )

### Define velocity thresholds

Velocity thresholds are also passed to`AnchoredDraggableState`'s constructor, and also expressed as a lambda:  

    val density = LocalDensity.current
    val anchoredDraggableState = AnchoredDraggableState(
        velocityThreshold = { with(density) { 125.dp.toPx() } },
        ...
    )

## Changes to the API surface

Find an overview of changes to the API surface below.

### `AnchoredDraggableState`

|                                                      `SwipeableState`                                                      |                                                                                             `AnchoredDraggableState`                                                                                             |
|----------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `open class SwipeableState`(initialValue: T, animationSpec: AnimationSpec = ..., confirmStateChange: (T) -> Boolean = ...) | `class AnchoredDraggableState`( initialValue: T, animationSpec: AnimationSpec = ..., confirmValueChange: (T) -> Boolean = ..., positionalThreshold: Density.(Float) -> Float = ..., velocityThreshold: Dp = ...) |
| `offset: State`                                                                                                            | `offset: Float` `requireOffset()`                                                                                                                                                                                |
| `progress: SwipeProgress`                                                                                                  | `progress: Float [0f..1f`\]                                                                                                                                                                                      |
| `currentValue: T`                                                                                                          | `currentValue: T`                                                                                                                                                                                                |
| `targetValue: T`                                                                                                           | `targetValue: T`                                                                                                                                                                                                 |
| `direction: Float [-1f, 0f, 1f`\]                                                                                          | N/A                                                                                                                                                                                                              |
| `suspend animateTo(` ` targetValue: T,` ` anim: AnimationSpec` = ...)                                                      | `suspend animateTo(` ` targetState: T,` ` velocity: Float =` ` lastVelocity)`                                                                                                                                    |
| `suspend snapTo(targetValue: T)`                                                                                           | `suspend snapTo(targetValue: T)`                                                                                                                                                                                 |
| `performDrag(delta: Float)`                                                                                                | `dispatchRawDelta(delta: Float)`                                                                                                                                                                                 |
| `suspend performFling(velocity: Float)`                                                                                    | `suspend settle(velocity: Float)`                                                                                                                                                                                |
| `isAnimationRunning: Boolean`                                                                                              | `isAnimationRunning: Boolean`                                                                                                                                                                                    |
|                                                                                                                            | `lastVelocity: Float`                                                                                                                                                                                            |

### `Modifier.anchoredDraggable`

|                           `Modifier.swipeable`                            |                                     `Modifier.anchoredDraggable`                                     |
|---------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| `state: SwipeableState`                                                   | `state: AnchoredDraggableState`                                                                      |
| `anchors: Map`                                                            | `AnchoredDraggableState#updateAnchors` `or` `AnchoredDraggableState#constructor`                     |
| `orientation: Orientation`                                                | `orientation: Orientation`                                                                           |
| `enabled: Boolean = true`                                                 | `enabled: Boolean = true`                                                                            |
| `reverseDirection: Boolean = false`                                       | `reverseDirection: Boolean = false`                                                                  |
| `interactionSource: MutableInteractionSource? = null`                     | `interactionSource: MutableInteractionSource? = null`                                                |
| `thresholds: (from: T, to: T) -> ThresholdConfig = FixedThreshold(56.dp)` | Passed to`AnchoredDraggableState`constructor as`positionalThreshold`                                 |
| `resistance: ResistanceConfig? = ...`                                     | Not yet supported. See[b/288084801](https://issuetracker.google.com/288084801)for the latest status. |
| `velocityThreshold: Dp = 125.dp`                                          | Passed to`AnchoredDraggable`constructor                                                              |