AnchoredDraggableState
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
initialValue | The 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
initialValue | The initial value of the state. |
anchors | The 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
initialValue | The initial value of the state. |
confirmValueChange | Optional 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
initialValue | The initial value of the state. |
anchors | The anchors of the state. Use updateAnchors to update the anchors later. |
confirmValueChange | Optional callback invoked to confirm or veto a pending state change. |
Properties
Deprecated ConfigurationMovedToModifier
lateinit var snapAnimationSpec: AnimationSpec<Float>
Deprecated ConfigurationMovedToModifier
lateinit var decayAnimationSpec: DecayAnimationSpec<Float>
var currentValue: T
The current value of the AnchoredDraggableState
.
That is the closest anchor point that the state has passed through.
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.
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.
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.
val isAnimationRunning: Boolean
Whether an animation is currently in progress.
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.
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.
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
from | The starting value used to calculate the distance |
to | The 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
newAnchors | The new anchors. |
newTarget | The 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
animationSpec | The 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
dragPriority | of the drag operation |
block | perform 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
targetValue | hint the target value that this anchoredDrag is intended to arrive to |
dragPriority | of the drag operation |
block | perform 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
fun <T : Any> Saver() =
Saver<AnchoredDraggableState<T>, T>(
save = { it.currentValue },
restore = { AnchoredDraggableState(initialValue = it) },
)
The default Saver
implementation for AnchoredDraggableState
.
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
.
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
.