TransitionManager progress manually
Asked Answered
F

1

12

I am currenlty exploring a somewhat complex UI similar to the BottomSheetBehaviour used in Google Maps, where one can animate an item from a collapsed state into an expanded state. The transition between those 2 states are Scene Transitions using the TransitionManager framework and work rather nicely.

I am now exploring a way to drag the expanded view again into the collapsed state and vice versa, but I did not find any obvious way to manually progress a scene transition.

What I would need would be something like: Transition.setAnimatedFraction(0.5f) based on the percentage the user has dragged between the 2 states.

A drag transition between those 2 states

Does anyone here have any idea on how to achieve that?

Fortissimo answered 16/8, 2017 at 15:9 Comment(7)
Hello @saberrider, Have you found out how to implement this? It would be great if you share your implementation.Tunisia
Hi @AminMousavi I have not found a nice and clean way to do it. The only way i achieved a very simple version of what i wanted to do, was to obtain Transition.getRunningAnimators() through reflection, stop all of them, and then set the animated time manually. It causes a lot of issues in various places and is definitely not production ready. To solve this properly would basically require to reengineer the TransitionManager and all the Transition classes respectively.Fortissimo
Here's an idea to try - create a custom TimeInterpolator that returns the 0..1 value based on the touch location. set the scene transition to use it.Chemarin
@auval I went down that path during my explorations. The issue is that no matter what timeinterpolator you come up with, the animation finishes after a given amount of time. therefore the transition will set the finished states on all objects after that time. You might suggest to just set time to something close to infinity, but that then leaves you with the situation that the TransitionManager.runningAnimators() are in a limbo state. and in order to restore order you will need again to use reflection to manually finish all of them.Fortissimo
In the Animator class there are pause(), resume() and setDuration(). If you set a non-interactive duration of 300ms for example, then during the touch gesture from srcY to dstY you make sure to increase the duration (for example we went 50% of the way) - to 450ms, set the interpolator according to normalized srcY and dstY, resume, and pause when reaching dstY. repeat on next drag point.Chemarin
That is exactly what i ended up doing and I described a couple of comments above. The problem is that without reflection you won't get to all involved animators unless you fork the whole transitionManager framework.Fortissimo
A while ago while one could make suggestions for the Android P grey/ blacklisted APIs I filed a feature request for google just for that topic: issuetracker.google.com/issues/110314356Fortissimo
S
4

Migrating your parent ViewGroup (whatever is ConstraintLayout, RelativeLayout or anything else) to MotionLayout you can achieve this using MotionLayout.progress (setProgress(float)) and loadLayoutDescription which give you power to process manually progress of a scene transition described in a motion scene.

Please see examples here.

Stubbs answered 11/3, 2019 at 4:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.