androidandroid-fragmentsandroid-navigation

FragmentContainerview animation ordering with popUpTo and popUpToInclusive


This is the setup in the Main Activity:

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/main_nav_graph" />

I have three fragments (A, B and C). I navigate from A to B and from B to C with a "slide in from right" animation like so:

        <action
            android:id="@+id/a_to_b"
            app:destination="@id/b"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/nothing"
            app:popEnterAnim="@anim/nothing"
            app:popExitAnim="@anim/slide_out_right" />

On Fragment C there is an "X" button that should cancel the flow and go back directly to Fragment A with a slide down animation while popping the back stack:

        <action
            android:id="@+id/cancel"
            app:destination="@id/a"
            app:enterAnim="@anim/nothing"
            app:exitAnim="@anim/slide_out_bottom"
            app:popEnterAnim="@anim/nothing"
            app:popExitAnim="@anim/nothing"
            app:popUpTo="@id/a"
            app:popUpToInclusive="true" />

Everything but the cancel action is working correctly. The problem is that it seems like the ordering on the cancel action is wrong. Fragment A is drawn over Fragment C, so you don`t see the slide out animation. I thought that the exiting Fragment should be drawn over the entering one when there is a pop happening.

Is there any way I can change this behaviour for a specific action?

Here are the animations I am using:

Nothing:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromYDelta="0%p"
    android:toYDelta="0%p" />

Slide in right:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromXDelta="100%p"
    android:toXDelta="0" />

Slide out bottom:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0%p" android:toYDelta="100%p"
    android:duration="300"/>

Solution

  • The problem was using a destination in the action, which seems to add a new entry instead of just going back. When removing the destination and also setting "popUpToInclusive" to "false" it works as expected:

            <action
                android:id="@+id/cancel"
                app:enterAnim="@anim/nothing"
                app:exitAnim="@anim/slide_out_bottom"
                app:popEnterAnim="@anim/nothing"
                app:popExitAnim="@anim/nothing"
                app:popUpTo="@id/a"
                app:popUpToInclusive="false" />