How do you animate from Dp.Unspecified to a specif...
# compose
l
How do you animate from Dp.Unspecified to a specific value?
l
I know about those APIs but how do you use them to animate between an a Dp.Unspecified and a specific value? If I literally do that it just snaps at the specified value once the animation is completed. Probably because it can't compute values in between (makes sense).
c
I don't know what you're asking. Sorry.
l
For instance:
Copy code
val buttonWidth by fromButtonToIndicator.animateDp(
    transitionSpec = {
        tween(durationMillis = 1500)
    },
    label = "Button Width"
) {
    if (it) 240.dp else Dp.Unspecified
}
If I run this code and use Modifier.width(buttonWidth) it doesn't actually animate from the automatic size the button got from it's own measurements and the new well defined 240.dp width. It is clear to me why it doesn't work but my question is: how would you do it?
I basically want to be able to animate from the self measured and assigned dimension to another, well defined one. Got any idea? Hopefully I was clear enough this time. 😅
i
I’m very new to all of this and probably late on this. But what I could figure out is that
Dp.Unspecified
is actually
Float.NaN
, and so the underlying interpolator doesn’t know what to do with it, unfortunately. So there is no transition, the end value is attributed directly because there is no way to “smoothly” transition from or to
NaN
. I managed an effect similar to what I think is desired by remembering the “self measured and assigned dimension” and using that instead of
Dp.Unspecified
for the value to be animated. It isn’t very pretty and for it to work, the very first time the component is shown, it has to be shown with
Dp.Unspecified
. This is the most important parts of the code I used to test, and it is by no means generic or tested:
Copy code
var isIndicator by remember { mutableStateOf(false) }
    var calculatedWidth by remember { mutableStateOf(0) }
    val buttonWidth by animateDpAsState(
        targetValue = if (calculatedWidth == 0) Dp.Unspecified else if (isIndicator) 40.dp else LocalDensity.current.run { calculatedWidth.toDp() }
    )

...

        modifier = Modifier
            .width(buttonWidth)
            .onSizeChanged {
                if (it.width > calculatedWidth) {
                    calculatedWidth = it.width
                }
            }