https://kotlinlang.org logo
#compose
Title
# compose
c

Colton Idle

11/29/2023, 1:17 AM
I sometimes find myself doing
Copy code
AnimatedVisibility(visible = someState != null) {
    MyUi(someState!!)
}
should compose/kotlin be able to figure out that I don't need !! or, am I setting up a potential footgun for myself here?
i

Ian Lake

11/29/2023, 1:35 AM
Does that actually work? I would think that
someState!!
would crash while the content is animating out (since setting
visible
to false doesn't mean the content instantly vanishes) - that's why
AnimatedContent
passes the lambda the
targetState
- so you don't have to hold onto it separately)
👆 2
👆🏾 1
z

Zoltan Demant

11/29/2023, 5:45 AM
Beware that AnimatedContent will also animate whenever someState changes. Shared a workaround here if you need!
i

Ian Lake

11/29/2023, 5:47 AM
Yeah, don't do that, just use the
contentKey
on
AnimatedContent
😅 1
z

Zoltan Demant

11/29/2023, 6:01 AM
Will that not still try to animate between values? Im pretty sure that was the behavior I was seeing at least but I havent revisited that in quite some time.
i

Ian Lake

11/29/2023, 6:33 AM
There's no animation between content with the same key
👌🏽 1
c

Colton Idle

11/29/2023, 8:14 AM
Ah okay. so it does work when "entering", but not during exit. TIL about AnimatedContent, thank you! This is what I ended up with
Copy code
AnimatedContent(targetState = someState) {
    if (it != null) {
      MyUi(it)
    }
}
the animation seems right, even though the other thread linked Albert mentioned that we don't need the inner null check. But I can't get it to work without that inner null check
Copy code
AnimatedContent(targetState = someState) {
    MyUi(it!!)
}
crashes
v

vide

11/29/2023, 8:22 AM
@Colton Idle that would animate only when entering, not exiting?
AnimatedContent
would work in both directions. You can't skip the inner null check with
AnimatedVisibility
c

Colton Idle

11/29/2023, 8:29 AM
ah. copy pasta'd wrong. editing my last message now
but yeah. basically. i still have to do the inner null check even with AnimatedContent
v

vide

11/29/2023, 8:38 AM
Yes, that's how you determine if you want content to show or not
targetState doesn't care about what your content is, it's completely up to you what to do with it inside
(it's less opinionated than AnimatedVisibility, which determines it for you, but it's a bit hairy with nullable values)
c

Colton Idle

11/29/2023, 8:41 AM
Interesting. Okay. so it seems like my final code is:
Copy code
AnimatedContent(targetState = someState) {
    if (it != null) {
      MyUi(it)
    }
}
thanks!
v

vide

11/29/2023, 8:47 AM
yes!
s

Stylianos Gakis

11/29/2023, 2:51 PM
Ah okay. so it does work when “entering”, but not during exit.
Well yeah, if during exiting the state is set to null, and you render nothing, then there will be nothing to render 😄 In places like these I’ve just passed a nullable object into
MyUi
and then that component can handle the null cases too, which is basically from the first frame it starts animating out, until it’s actually out of composition. And that results in a nice animation out too. It’s just a declarative UI thing, even as it’s animating out, you still need to tell it what it should look like.
z

Zoltan Demant

11/29/2023, 3:17 PM
@Stylianos Gakis, can you elaborate on
In places like these I’ve just passed a nullable object into
MyUi
and then that component can handle the null cases too
Do you mean doing something like remembering the value so that it still exists for the out animation? Just curious, thats effectively what Ive been doing, but always fun to explore new ways!
s

Stylianos Gakis

11/29/2023, 3:23 PM
In some cases it’s just that the component is ready to handle a null input. If it’s a card that shows some information, well, then it just shows no information, but keeps the height as it is. So practically what you see as it’s animating out is that on the first frame, the content is gone, and it starts shrinking a bit, and then on the next frames you just continue showing nothing, and continue animating out. Doing a remember, while also making sure to update the value when a new input comes which is not null, but not updating the value when the new input is null is also a possibility, which I would only do in places where the thing animating out is important enough to warrant all the extra work to have it “remember” the last valid input. Definitely makes the code harder to reason about only to bring in better animation support, but when it’s needed, then it’s worth it.
z

Zoltan Demant

11/29/2023, 3:24 PM
Gotcha, agreed 👍🏽
c

Colton Idle

11/29/2023, 5:13 PM
In this case, it seems to keep the content there while animating out, which is nice because thats the behavior i want.
s

Stylianos Gakis

11/29/2023, 7:14 PM
That doesn't sound right. What does the real snippet look like?
c

Colton Idle

11/29/2023, 7:52 PM
my final code is: AnimatedContent(targetState = someState) { if (it != null) { MyUi(it) } }
i

Ian Lake

11/29/2023, 8:28 PM
Yep, that'll keep
it
around all the way until it finishes animating out, even if nothing else outside of the
AnimatedContent
is keeping that object alive
❤️ 1
c

Colton Idle

11/29/2023, 9:16 PM
I swear I've been doing compose for a while but there's always something new to learn.
92 Views