Status Update
Comments
di...@gmail.com <di...@gmail.com> #2
Can you try with the latest snapshot? Not reproducible for me on androidx-main.
ti...@google.com <ti...@google.com> #3
Ok, after trying a couple more versions, realized this is a duplicate of
From the release notes:
AndroidView's update callback's first invocation will now be defered until the view is attached, instead of running when the composition that introduces the AndroidView is applied. This fixes a bug where the update callback wouldn't be invalidated if a state it read was changed immediately by an effect. (Ie9438,
) b/291094055
Sorry for the confusion!
di...@gmail.com <di...@gmail.com> #4
Definitely reasonable to treat the shared element as unmatched, but I'm not sure how to achieve a good-looking animation in that case. I want it to "simulate" being matched, with the element sliding in from I expect it to be if it were composed. Is there a way to achieve that with current APIs?
ti...@google.com <ti...@google.com> #5
If you add an animateEnterExit
modifier to define a slide before Modifier.sharedElement
, it should slide when there's no match, and transition as a shared element when matched.
Would that solve your use case?
di...@gmail.com <di...@gmail.com> #6
Sorry for the delay.
My use case is a feed<->detail transition, where the detail screen can scroll the shared element off screen (causing it to dispose because it's in a lazy list). if I apply animateEnterExit
to feed elements, all the other non-matched ones also get the animations, as the lack of a match effectively means no special animation for that feed element.
That said, even if I could apply it selectively, in order to achieve the desired effect of the element transitioning in from the top of the screen, I think I would have to store the coords of the feed and the feed element, so I can set initialOffset = { -feedCoords.localPositionOf(feedElementCoords).y }
ti...@google.com <ti...@google.com> #7
Thanks for explaining the use case.
While animating shared elements to a given coords is technically possible, the functionality doesn't fit in the shared element API, as it's no longer shared elements.
What you had initially suggested in
di...@gmail.com <di...@gmail.com> #8
What would unpinning it affect? As I understand it that would cause the item to dispose, which then means the shared element in the feed has no match. At that point it's a normal non-shared transition.
ti...@google.com <ti...@google.com> #9
Re unpinnig: depending on what's being saved, unpinning before disposal would avoid the pinning from persisting when the screen is restored.
Alternatively, when the screen is initially composed or restored, can you defer pinning the shared content until it has been composed?
di...@gmail.com <di...@gmail.com> #10
I might not have communicated my goal correctly. From what I can tell, pinning the content gives me a more desirable effect in every case. In the detail screen, while the element is scrolled off the top of the screen, when I go back to the feed it moves downwards, which is spatially consistent with where I expect it to be. If it is unpinned, there's no shared element match, so the corresponding item in the feed just fades in like every other item, losing spatial consistency. I'm trying to achieve the effect I get when it's pinned, but in all cases, even when that content hasn't composed at all (like in the state restoration example).
Alternatively, when the screen is initially composed or restored, can you defer pinning the shared content until it has been composed?
I pin the content (via LocalPinnableContainer.current?.pin()
inside the content's composition, so I think that happens naturally.
Just to avoid ambiguity, by pinning I'm talking about the PinnableContainer::pin
function, not any visual effect like a sticky header.
ti...@google.com <ti...@google.com> #11
Thanks for the clarification. Seems like you want the effect of shared elements animating towards the pinned position (on screen or off screen), regardless of whether the item has been composed at all.
In that case, I would suggest creating a place holder off screen, as a sibling to the lazy list. This place holder would have the shared element modifier and key, and is only enabled before the real item is composed or after it's disposed.
Description
Jetpack Compose component used: Animation
I have a shared transition where the element being matched in the destination screen can be scrolled off-screen. In a lazy container, this results in that element being disposed, and thus unable to be a match for `Modifier.sharedElement()`. This gives an undesirable animation when returning from that destination screen, as the element in the previous screen uses the default animation. I would like it to instead animate from a location at/near where it was last scrolled to. While I could use `LocalPinnableContainer` in that example, that doesn't work if my screen restores its state after already being scrolled (as the element will have never composed at all).
An example of an API that would suit my use case would be:
```
// Source screen
Item(
item,
Modifier.sharedElement(
rememberSharedContentState(item.key),
fallbackBounds = { lastMatchedElementBounds ->
lastMatchedElementBounds
}
)
)
```