Rainmaker
Rainmaker

Reputation: 11090

Slide animation with navigation component

I'm using JetPack navigation component to navigate between fragments. I've added slide animation between 2 fragments in graph xml:

<action
    android:id="@+id/action_Fragment_to_DetailsFragment"
    app:enterAnim="@anim/slide_left"
    app:popEnterAnim="@anim/slide_right"
    app:destination="@id/DetailsFragment" />

The problem is - b/c I'm using navigation component and it uses fragmentManager.replace(), instead of fragmentManager.add(), instead of smooth animation I see that:

  1. the first fragment disappears

  2. animation of 2nd fragment is being triggered and sliding new fragment to a screen

  3. 2nd fragment appears on a screen.

And b/c I have different content on both screens, it looks buggy. I want to implement is "like in IOS" where user sees 2 layers of screens, sliding from each other. Is there a way to implement it with Navigation component which doesn't support "fragmentManager.add()"?

I've also tried

app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"

but situation is not much better.

Upvotes: 14

Views: 15388

Answers (3)

artonbej
artonbej

Reputation: 287

If anyone wants to achieve this animation in fragments with enter and exit.

https://i.imgur.com/vBKZPsr.gif

<action
    android:id="@+id/action_sign_in_to_fragmentMemberValidate"
    app:destination="@id/fragmentMemberValidate"
    app:enterAnim="@anim/nav_slide_in_right"
    app:exitAnim="@anim/nav_slide_out_left"
    app:popExitAnim="@anim/nav_slide_out_right"
    app:popEnterAnim="@anim/nav_slide_in_left"/>

nav_slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXDelta="100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

nav_slide_out_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="-100%"
        android:toYDelta="0%" />
</set>

nav_slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="100%"
        android:toYDelta="0%" />
</set>

nav_slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXDelta="-100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

Upvotes: 7

Rainmaker
Rainmaker

Reputation: 11090

Finally I found the way how to do it.

  1. in a graph, set the animation:

<action
        android:id="@+id/action_DetailsFragment"
        app:enterAnim="@anim/slide_left"
        app:exitAnim="@anim/wait_anim"
        app:popEnterAnim="@anim/wait_anim"
        app:popExitAnim="@anim/slide_right"
        app:destination="@id/detailsFragment" />

  1. Creatie animations:

    slide_left.xml

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

slide_right.xml

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

wait_anim.xml

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

  1. To make it look better, in DetailsFragment add:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) ViewCompat.setTranslationZ(getView()!!, 100f) }

  2. You can also add sharedElementTransitions to make your animation more unique.

Upvotes: 27

Rainmaker
Rainmaker

Reputation: 11090

So far I was ably to improve animation using:

  • SharedElement for some parts of a screen

  • adding alpha to the animation

  • increasing the speed of a slide animation so the "empty space" is not that visible

But still wasn't able to implement "IOS - like" slide animation.

Upvotes: 1

Related Questions