arkivanov / Decompose

Kotlin Multiplatform lifecycle-aware business logic components (aka BLoCs) with routing (navigation) and pluggable UI (Jetpack Compose, SwiftUI, JS React, etc.)
https://arkivanov.github.io/Decompose
Apache License 2.0
2.15k stars 84 forks source link

Consider adding some sort of integration to allow easier use of shared element transitions between screens. #690

Closed StylianosGakis closed 1 month ago

StylianosGakis commented 5 months ago

With the shared element transitions being introduced in the latest alphas https://github.com/androidx/androidx/commit/c5f36c050e6ec86e8a504031b3cd7602a11f4d9e it's gonna be fun to be able to use it in an app using Decompose when navigating between screens.

What the library can provide to the child components so that they are able to make use of it is most likely some way to access the AnimatedContentScope or just AnimatedVisibilityScope which is required here. This scope would be the one which is currently animating between the two states that are being navigated, to -> from, and works with stuff like the back gesture gradually progressing this animation.

To give some examples:

The androidx.navigation library provides the destination's content with the AnimatedContentScope here so passing that one inside sharedElement makes it trivial to make something like this work, in this commit. The steps inside the app code were basically:

For circuit: I hacked away this sample https://github.com/StylianosGakis/circuit/pull/1 by using the AnimatedContent which they were using internally anyway and exposing its state to its children. This is not how they will do it in the real release I bet, but in any case it was just an experiment to see what would be the minimum amount of work needed to get the same behavior going there.

For decompose I tried looking a bit into it but I didn't find the right spot to hook everything together so I had to give up for now at least. I would love to hear your thoughts about this and what the path of adopting this for decompose will look like.

Note that it could be possible that there's an easy way to do this here that I completely missed due to my inexperience with Decompose. If that is the case I would love to see how it is possible so that I can play more with it myself after that.

arkivanov commented 5 months ago

Thanks for raising this issue! The biggest challenge for now seems to be that Decompose uses its own stack animation API, and so it might be difficult to provide AnimatedVisibilityScope. The custom animation API allows writing custom animations easily almost without limitations.

We'll need to wait until the shared transitions API is available in Multiplatform Compose, then I will investigate and provide updates here. We might need a separate animation API to support shared transitions.

arkivanov commented 5 months ago

There is also a modifier like sharedElementWithCallerManagedVisibility, which might work.

StylianosGakis commented 5 months ago

The custom animation API allows writing custom animations easily almost without limitations.

This sounds very enticing, I would be interested in exploring this further if I can get a better idea of what you mean here!

We'll need to wait until the shared transitions API is available in Multiplatform Compose

Yeap, absolutely. I am raising this issue perhaps a bit early, but it's good to have in mind regardless.

sharedElementWithCallerManagedVisibility

Yeap, I will give this a shot too, thanks!

arkivanov commented 5 months ago

I would be interested in exploring this further if I can get a better idea of what you mean here

Most of the APIs are described in the docs: https://arkivanov.github.io/Decompose/extensions/compose/#animations Let me know if you need more information.

arkivanov commented 4 months ago

Well, it was pretty easy to create a new simple example with shared transitions, without predictive back support and without any changes in Decompose. I've uploaded the example to a separate branch. I've also extracted a separate commit that just adds the shared transitions on their own.

The support of the predictive back gesture is tricky and most likely will require some API changes. I will keep providing updates here.

https://github.com/arkivanov/Decompose/assets/26204457/005ab513-55e6-4bbe-b261-c2a6ff1ee8c2

arkivanov commented 4 months ago

I've checked the predictive back gesture support further: currently it looks like we'll need to change both the animation and and the predictive back gesture APIs. Indeed, the API will need to provide AnimatedVisibilityScope. Most likely this will be implemented in the next 4.0 major release, together with #695. Or maybe as a separate set of experimental APIs in a minor 3.x update.

arkivanov commented 4 months ago

It would be nice to document the option with shared traditions but without predictive back gesture for now.

arkivanov commented 2 months ago

Just a heads-up: I made a good progress on this a while ago, but had to put it on hold due the upcoming Droidcon Berlin conference (need to prepare a talk). Will continue working on this right after the conference. Intend to release something by the end of July.

arkivanov commented 2 months ago

Added shared transitions to the main sample. In the separate branch sample-shared-anim for now, while waiting for a stable Multiplatform Compose 1.7.x. The back gesture is not yet supported.

arkivanov commented 1 month ago

Almost done, just need to polish some things.

https://github.com/arkivanov/Decompose/assets/26204457/f50de889-59a6-4465-9859-c75ca86647af

arkivanov commented 1 month ago

Currently waiting for Kotlin 2.0.10 as it contains a necessary fix for https://github.com/JetBrains/compose-multiplatform/issues/5045#issuecomment-2213504878.

arkivanov commented 1 month ago

Currently waiting for Kotlin 2.0.10 as it contains a necessary fix for JetBrains/compose-multiplatform#5045 (comment).

Still waiting.

https://github.com/user-attachments/assets/7e435aea-2cff-492d-9435-74c4c3ff3159

arkivanov commented 1 month ago

Kotlin 2.0.10 is out. Will try to make a release soon.