I'm using navigationBar from m3. Sometimes I will ...
# compose
c
I'm using navigationBar from m3. Sometimes I will have 4 tabs... sometimes I will have 3 depending on whether the user made a purchase. I have this working, but it looks janky because of how the nav bar icon appears. Is there any way to add some animation to navigationBar when adding an extra tab? My tab code is essentially this from the docs
s
Copy code
fun 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 BottomNavigationItem
c
Was not expecting sooo much code for that (but I will of course try it out and am very thankful!). @Doris Liu just as a sanity check... is there anything else I can do?
s
This probably comes from here anyway https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]nimation/AnimatedPlacementDemo.kt;l=86-117?q=AnimatePlacement I don't see any other built-in modifier doing this work for you, so might as well rip that one from the demos
c
oh cool. okay it'll be easier to submit the PR if I can say that i ripped it from the androidx repo.
s
Yes,this one is fork from AOSP demo
❤️ 1
c
I'm having a hard time making the animation just a zoomIn/zoomOut sort of thing, but it definitely looks better than the static hide/show. thanks everyone