Search code examples
androidandroid-fragmentsandroid-transitionsandroid-architecture-navigation

Android Fragment: Different animations for enter and return


I'm showing a fragment using the androidx navigation architecture component.

The fragment is shown by an ArcMotion shared element transition, but the exit transition should be a simple slide down.

I'm showing the fragment the following way:

findNavController().navigate(
    EntriesFragmentDirections.actionEntriesFragmentToNewBookEntryFragment(
        bookEntryType = mEntriesViewPager.currentItem,
        enterTransition = R.transition.new_book_entry_enter,
        exitTransition = R.transition.new_book_entry_exit
    ),
    FragmentNavigatorExtras(fabEntriesNewBookEntry to getString(R.string.transition_new_book_entry_fragment))
)

And I apply the transitions in the fragment in onCreate:

sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(args.enterTransition)
exitTransition = TransitionInflater.from(requireContext()).inflateTransition(args.exitTransition)

The enter transition is working well, but the exit transition is still the reversed enter transition.

The enter transition xml:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:duration="@android:integer/config_mediumAnimTime">

    <transition
        class="at.guger.moneybook.ui.transition.MorphTransform"
        app:endColor="?colorSurface"
        app:endCornerRadius="@dimen/zero"
        app:startColor="?colorSecondary"
        app:startCornerRadius="@dimen/fabRadius" />

</transitionSet>

The exit transition xml:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime">

    <slide android:slideEdge="bottom" />

</transitionSet>

Solution

  • The solution here is to inflate the transitions in the fragment's onCreate:

    private val args: NewBookEntryFragmentArgs by navArgs()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        if (Utils.isLollipop() && args.enterTransition > 0 && args.exitTransition > 0) {
            sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(args.enterTransition)
            sharedElementReturnTransition = null
            returnTransition = TransitionInflater.from(requireContext()).inflateTransition(args.exitTransition)
    }
    

    The navigation call looks the following way:

    findNavController().navigate(
        EntriesFragmentDirections.actionEntriesFragmentToNewBookEntryFragment(
            bookEntryType = mEntriesViewPager.currentItem,
            enterTransition = R.transition.new_book_entry_enter,
            exitTransition = R.transition.new_book_entry_exit
        ),
        FragmentNavigatorExtras(fabEntriesNewBookEntry to getString(R.string.transition_new_book_entry_fragment))
    )
    

    new_book_entry_enter.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:duration="@android:integer/config_mediumAnimTime">
    
        <transition
            class="at.guger.moneybook.ui.transition.MorphTransform"
            app:endColor="?colorSurface"
            app:endCornerRadius="@dimen/zero"
            app:startColor="?colorSecondary"
            app:startCornerRadius="@dimen/fabRadius" />
    
    </transitionSet>
    

    new_book_entry_exit.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="@android:integer/config_mediumAnimTime">
    
        <slide
            android:interpolator="@android:interpolator/accelerate_quint"
            android:slideEdge="bottom" />
    
    </transitionSet>