AnchoredDraggableState

Class

Common
class AnchoredDraggableState<T>(initialValue: T)

State of the anchoredDraggable modifier. Use the constructor overload with anchors if the anchors are defined in composition, or update the anchors using updateAnchors.

This contains necessary information about any ongoing drag or animation and provides methods to change the state either immediately or by starting an animation.

Parameters

initialValueThe initial value of the state.

Secondary Constructors

constructor(initialValue: T, anchors: DraggableAnchors<T>) : this(initialValue) {
    this.anchors = anchors
    trySnapTo(initialValue)
}

Construct an AnchoredDraggableState instance with anchors.

Parameters

initialValueThe initial value of the state.
anchorsThe anchors of the state. Use updateAnchors to update the anchors later.
constructor(
    initialValue: T,
    confirmValueChange: (newValue: T) -> Boolean,
) : this(initialValue) {
    this.confirmValueChange = confirmValueChange
}

Construct an AnchoredDraggableState instance with anchors.

Parameters

initialValueThe initial value of the state.
confirmValueChangeOptional callback invoked to confirm or veto a pending state change.
constructor(
    initialValue: T,
    anchors: DraggableAnchors<T>,
    confirmValueChange: (newValue: T) -> Boolean = { true },
) : this(initialValue, confirmValueChange) {
    this.anchors = anchors
    trySnapTo(initialValue)
}

Construct an AnchoredDraggableState instance with anchors.

Parameters

initialValueThe initial value of the state.
anchorsThe anchors of the state. Use updateAnchors to update the anchors later.
confirmValueChangeOptional callback invoked to confirm or veto a pending state change.

Properties

Common

Deprecated ConfigurationMovedToModifier

lateinit var snapAnimationSpec: AnimationSpec<Float>
Common

Deprecated ConfigurationMovedToModifier

lateinit var decayAnimationSpec: DecayAnimationSpec<Float>
Common
var currentValue: T

The current value of the AnchoredDraggableState.

That is the closest anchor point that the state has passed through.

Common
var settledValue: T

The value the AnchoredDraggableState is currently settled at.

When progressing through multiple anchors, e.g. A -> B -> C, settledValue will stay the same until settled at an anchor, while currentValue will update to the closest anchor.

Common
val targetValue: T

The target value. This is the closest value to the current offset. If no interactions like animations or drags are in progress, this will be the current value.

Common
var offset: Float

The current offset, or Float.NaN if it has not been initialized yet.

The offset will be initialized when the anchors are first set through updateAnchors.

Strongly consider using requireOffset which will throw if the offset is read before it is initialized. This helps catch issues early in your workflow.

Common
val isAnimationRunning: Boolean

Whether an animation is currently in progress.

Common

Deprecated Use the progress function to query the progress between two specified anchors.

@get:FloatRange(from = 0.0, to = 1.0)
val progress: Float

The fraction of the progress going from settledValue to targetValue, within 0f..1f bounds, or 1f if the AnchoredDraggableState is in a settled state.

Common
var lastVelocity: Float

The velocity of the last known animation. Gets reset to 0f when an animation completes successfully, but does not get reset when an animation gets interrupted. You can use this value to provide smooth reconciliation behavior when re-targeting an animation.

Common
var anchors: DraggableAnchors<T>

Functions

fun requireOffset(): Float

Require the current offset.

@FloatRange(from = 0.0, to = 1.0)
    fun progress(from: T, to: T): Float

The fraction of the offset between from and to, as a fraction between 0f..1f, or 1f if from is equal to to.

Parameters

fromThe starting value used to calculate the distance
toThe end value used to calculate the distance
fun updateAnchors(
        newAnchors: DraggableAnchors<T>,
        newTarget: T =
            if (!offset.isNaN()) {
                newAnchors.closestAnchor(offset) ?: targetValue
            } else targetValue,
    )

Update the anchors. If there is no ongoing anchoredDrag operation, snap to the newTarget, otherwise restart the ongoing anchoredDrag operation (e.g. an animation) with the new anchors.

If your anchors depend on the size of the layout, updateAnchors should be called in the layout (placement) phase, e.g. through Modifier.onSizeChanged. This ensures that the state is set up within the same frame. For static anchors, or anchors with different data dependencies, updateAnchors is safe to be called from side effects or layout.

Parameters

newAnchorsThe new anchors.
newTargetThe new target, by default the closest anchor or the current target if there are no anchors.
suspend fun settle(animationSpec: AnimationSpec<Float>)

Find the closest anchor and settle at it with the given animationSpec.

Parameters

animationSpecThe animation spec that will be used to animate to the closest anchor.
suspend fun settle(velocity: Float): Float

Find the closest anchor, taking into account the velocityThreshold and positionalThreshold, and settle at it with an animation.

If the velocity is lower than the velocityThreshold, the closest anchor by distance and positionalThreshold will be the target. If the velocity is higher than the velocityThreshold, the positionalThreshold will not be considered and the next anchor in the direction indicated by the sign of the velocity will be the target.

Based on the velocity, either snapAnimationSpec or decayAnimationSpec will be used to animate towards the target.

Returns

The velocity consumed in the animation
suspend fun anchoredDrag(
        dragPriority: MutatePriority = MutatePriority.Default,
        block: suspend AnchoredDragScope.(anchors: DraggableAnchors<T>) -> Unit,
    )

Call this function to take control of drag logic and perform anchored drag with the latest anchors.

All actions that change the offset of this AnchoredDraggableState must be performed within an anchoredDrag block (even if they don't call any other methods on this object) in order to guarantee that mutual exclusion is enforced.

If anchoredDrag is called from elsewhere with the dragPriority higher or equal to ongoing drag, the ongoing drag will be cancelled.

If the anchors change while the block is being executed, it will be cancelled and re-executed with the latest anchors and target. This allows you to target the correct state.

Parameters

dragPriorityof the drag operation
blockperform anchored drag given the current anchor provided
suspend fun anchoredDrag(
        targetValue: T,
        dragPriority: MutatePriority = MutatePriority.Default,
        block: suspend AnchoredDragScope.(anchor: DraggableAnchors<T>, targetValue: T) -> Unit,
    )

Call this function to take control of drag logic and perform anchored drag with the latest anchors and target.

All actions that change the offset of this AnchoredDraggableState must be performed within an anchoredDrag block (even if they don't call any other methods on this object) in order to guarantee that mutual exclusion is enforced.

This overload allows the caller to hint the target value that this anchoredDrag is intended to arrive to. This will set AnchoredDraggableState.targetValue to provided value so consumers can reflect it in their UIs.

If the anchors or AnchoredDraggableState.targetValue change while the block is being executed, it will be cancelled and re-executed with the latest anchors and target. This allows you to target the correct state.

If anchoredDrag is called from elsewhere with the dragPriority higher or equal to ongoing drag, the ongoing drag will be cancelled.

Parameters

targetValuehint the target value that this anchoredDrag is intended to arrive to
dragPriorityof the drag operation
blockperform anchored drag given the current anchor provided
fun dispatchRawDelta(delta: Float): Float

Drag by the delta, coerce it in the bounds and dispatch it to the AnchoredDraggableState.

Returns

The delta the consumed by the AnchoredDraggableState

Companion Object

Methods

Common
fun <T : Any> Saver() =
            Saver<AnchoredDraggableState<T>, T>(
                save = { it.currentValue },
                restore = { AnchoredDraggableState(initialValue = it) },
            )

The default Saver implementation for AnchoredDraggableState.

Common

Deprecated ConfirmValueChangeDeprecated

fun <T : Any> Saver(confirmValueChange: (T) -> Boolean = { true }) =
            Saver<AnchoredDraggableState<T>, T>(
                save = { it.currentValue },
                restore = {
                    AnchoredDraggableState(
                        initialValue = it,
                        confirmValueChange = confirmValueChange,
                    )
                },
            )

The default Saver implementation for AnchoredDraggableState.

Common

Deprecated ConfigurationMovedToModifier

fun <T : Any> Saver(
            snapAnimationSpec: AnimationSpec<Float>,
            decayAnimationSpec: DecayAnimationSpec<Float>,
            positionalThreshold: (distance: Float) -> Float,
            velocityThreshold: () -> Float,
            confirmValueChange: (T) -> Boolean = { true },
        ): Saver<AnchoredDraggableState<T>, T>

The default Saver implementation for AnchoredDraggableState.