`Modifier.animateContentSize` . Is there a version...
# compose
d
Modifier.animateContentSize
. Is there a version of this like
Modifier.animateContentPosition
? Or how would I go about writing my own?
Modifier.layout
doesn't provide a position.
On second thought, I don't think such a modifier is a good idea in general. It won't even work for what I wanted to use it for.
d
Oh? why don't you think it's a good idea in general?
d
I feel animating a
LayoutNode
from position to position is something the parent layout should probably do. (At least for what I had in mind)
The node can always animate itself in it's local coordinate system if it wants to shake or something.
I wanted the modifier to implement
LazyColumn
re-ordering animations, then realised that it would be really broken for scrolling. Which is why I concluded that
LazyColumn
should be doing the animations instead of the items.
Also,
animateContentPosition
would probably require global position, which is more/less impossible to get within the same frame/composition. Actually, not global position per se, but it'll have to climb up the layout hierarchy to some "global enough" layout to get the position.
At which point, it's probably also best if the parent just handled the animation anyway. Since one has to find this "global enough" layout.
d
The way I see it is the parent is responsible for placing the child, but the child can decide whether it wants to jump to the new placement (when there's a change) or animate to it. Of course, it makes sense to do that in parent. It's also quite interesting to insert an additional modifier between child and parent for such an animation. In that sense, it's like
animateContentSize
Actually, not global position per se, but it'll have to climb up the layout hierarchy to some "global enough" layout to get the position.
Seems like you are trying to animate the position relative to an
indirect
parent? With direct parents, you could use
LayoutCoordinates#positionInParent()
to get the child placement
d
Ah, I kinda agree with that.
It's also quite interesting to insert an additional modifier between child and parent for such an animation
This sounds like more or less what I'm looking for. The only pesky thing is I need to disable the animation during scroll. Or rather, scroll should be one layer above the "global enough" parent. Maybe
LazyColumn
is not composable enough.
Where would I get
LayoutCoordinates
from? I don't think
Layout
or
Modifier.layout
provides this?
d
You'd need to rely on
onGlobalPositioned
modifier to get the
LayoutCoordinates
. I'm playing around with an idea around
Modifier.animatePlacement
, I can upload the code if you are interested.`
d
Yes please! I'm super interested!!
d
Won't that stutter a bit?
onGlaballyPositioned
gives the position a frame too late I think.
d
This is relying on
onGlobalPositioned
for acquiring LayoutCoordinates for the first time. It will be in the same first frame, but after draw. Being late on the first frame is not a problem since we don't animate when layout first show up anyways. The subsequent
LayoutCoordinates#positionInParent
are queried during placement time, which triggers a calculation (instead of using the cached position from last frame). I don't think there should be any stutter, nor do I see any. But it does have the same issue with scrolling as you mentioned earlier, since scrolling also changes the "position in parent". 🙂
d
Ahhh I get it now. I was under the impression that
LayoutCoordinates
was an immutable snapshot but it seems to be a persistent reference to the parent node. So
positionInParent
is always the current value.
In the demo you use
AnimatedVisibility
, which will hide any stutter I think. If you straight up removed the node, I think the stutter, if there is any, will show itself. I should try this out myself.
d
The AnimatedVisibility just fades out the item, position change of the other item (that has the
animatePlacement
modifier) doesn't start until that exit animation is done and item is removed. I had the immediate removal before. I don't see why it would stutter. Even if it's one frame behind, you'd just see a spring chain like effect. Yes, please feel free to try it yourself. 🙂