Propagating Transitions in Android
Follow along with the demo app on Github.
Transitions [in Android] and succulents [in real life] aren’t too different when it comes to a topic called propagation.
Propagating a succulent involves tearing off and re-planting its leaves, which act like seeds that grow into their own succulents. Transition effects within a ViewGroup can be propagated amongst its children in order to achieve a staggered and more choreographed effect.
Okay, so they actually are very different. I just wanted to mention plants.
As mentioned before, propagating a transition helps you implement the staggered fading or sliding seen in the material design docs.
The magic lies in the Transition.setPropagation(TransitionPropagation)
function. A TransactionPropagation
holds the logic for offsetting the start delays of the individual targets within the transition.
Planting the seeds for propagation
A Transition needs two things in order to prepare for a propagation:
- A
TransitionPropagation
object that will handle the logic for offsetting the start delays. Android comes baked in with two really great propagations:CircularPropagation
(seen in the above gif) andSidePropagation
. We just need to instantiate the propagation:
val propagation: TransitionPropagation = CircularPropagation()
- An epicenter. This a view that the animation will propagate from. The Transition framework wants a
Transition.EpicenterCallback
that implementsonGetEpicenter(transition: Transition?)
. We can write an extension function to get an epicenter from a view.
What it actually looks like
Given a Fade(Fade.IN)
transition with an 800 ms duration, we get something that looks like this:
This is very subtle and probably what works better in an app (so your users aren’t waiting too long), but for demo purposes we’ll slow it down to a full 2 seconds so we can easily see the propagation.
I wouldn’t recommend using a 2-second transition — your users will probably get extremely annoyed as they get used to the app and will probably want to turn it off. Try to find a balance between subtlety and wow-factor.
Propagation plays really nicely with simple transitions that are already baked into the app, such as Fade
, Slide
, or TransitionSet
s of them.
Slide
Using Slide(Gravity.BOTTOM)
, elements appear to slide upwards with a slight parallax effect. This is due to the staggered start delays of the invidual items within the constraint layout.
Fade and Slide
Compositions of transitions can also be used. Simply combining fade and slide works really well.
transition = TransitionSet()
.addTransition(Fade(Fade.IN)
.setInterpolator { (it - 0.5f) * 2 })
.addTransition(Slide(Gravity.TOP))
We set a custom interpolator during only the Fade transition. This essentially starts the Fade halfway through the animation’s lifetime but makes it go twice as fast after the halfway point.
This most closely resembles the first gif as given by material design.
One last transition
Finally, there is another baked-in transition that we can use other than Fade and Slide.
transition = Explode()
Conclusion
Propagations can have a dramatic effect on how a transition executes. Take care with not going too overboard with the effects. Let propagations be another creative tool for making the transition your product needs.
I encourage you to check out, checkout, and submit issues or pull requests in the repo for this demo.
Please let me know any and all feedback you have! Comment below or shoot me an email at [email protected].