How to Listen to Transition Completed on Android Fragment Transition with Navigation Component?

Viewed 830

I have this one fragment that loads tons of data and display it into recyclerView. If I open this fragment directly without waiting for transition completed the transition will become choppy because the thread is throttled by recyclerView update data

So I want to delay this update data until fragment transition completed.

But sadly I have yet to find any way to listen to fragment transition completed so my current approach is to delay the data update for several miliseconds until using Handler() , but I believe this is very hacky and not elegant solution

Handler().postDelayed({
//do something
}, 500)

I need help to know what method should I call to listen to the fragment transition completed . Thank youuu

3 Answers

Fragments offer two ways of avoiding this problem:

  1. You can avoid starting your transition until your data is loaded by postponing your transition. This ensures that your RecyclerView is already populated with data that can be used for shared element transitions, etc. This is the general recommendation and ensures a smooth transition on all versions of Fragments.

  2. When using Fragment 1.3.0 or higher, your fragment will not reach the resumed state until any transitions or Animators (specifically not Animations) are complete. This allows you to use onResume() as a signal that your transitions are complete.

hmm I somehow did it with onCreateAnimation following this answer

override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
    val anim: Animation = AnimationUtils.loadAnimation(activity, nextAnim)
    anim.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationStart(animation: Animation?) {}
        override fun onAnimationRepeat(animation: Animation?) {}
        override fun onAnimationEnd(animation: Animation?) {
            if (enter) {
                //load and update recyclerView here
            }
        }
    })
    return anim
}

If you have to use animations, rather than Transitions or Animators, you can extract the animation duration into an integer resource and set the animation duration to it:

<!-- values/durations.xml -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="animation_duration">220</integer>
</resources>

<!-- anim/transition.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >
    <alpha android:duration="@integer/animation_duration" android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>

And then retrieve it in your fragment:

val animationDuration = requireContext().resources.getInteger(R.integer.animation_duration)
Handler().postDelayed({
//do something
}, animationDuration)
Related