Colton Idle
07/02/2025, 12:56 AMSanlorng
07/02/2025, 5:50 AMfun Modifier.animatePlacement(animationSpec: AnimationSpec<Offset> = spring(stiffness = Spring.StiffnessMediumLow)): Modifier =
then(AnimatePlacementElement(animationSpec))
private data class AnimatePlacementElement(
val animationSpec: AnimationSpec<Offset>,
) : ModifierNodeElement<AnimatePlacementModifier>() {
override fun create(): AnimatePlacementModifier = AnimatePlacementModifier(animationSpec = animationSpec)
override fun update(node: AnimatePlacementModifier) {
node.animationSpec = animationSpec
}
}
private class AnimatePlacementModifier(
var animationSpec: AnimationSpec<Offset>,
) : Modifier.Node(),
LayoutAwareModifierNode,
LayoutModifierNode {
private var targetOffset by mutableStateOf(Offset.Zero)
private var animatable by mutableStateOf<Animatable<Offset, AnimationVector2D>?>(null)
override fun MeasureScope.measure(
measurable: Measurable,
constraints: Constraints,
): MeasureResult {
val placeable = measurable.measure(constraints)
return layout(placeable.width, placeable.height) {
placeable.place(
animatable?.let { (it.value - targetOffset).round() } ?: IntOffset.Zero,
)
}
}
override fun onPlaced(coordinates: LayoutCoordinates) {
targetOffset = coordinates.positionInParent()
val anim =
animatable ?: Animatable(targetOffset, Offset.VectorConverter)
.also { animatable = it }
if (anim.targetValue != targetOffset) {
coroutineScope.launch {
anim.animateTo(targetOffset, animationSpec)
}
}
animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
}
}
Add this modifier to each BottomNavigationItemColton Idle
07/02/2025, 12:13 PMStylianos Gakis
07/02/2025, 12:50 PMColton Idle
07/02/2025, 1:06 PMSanlorng
07/02/2025, 2:13 PMColton Idle
07/03/2025, 3:21 PM