share
Stack OverflowAnimate the transition between fragments
[+303] [9] Labeeb Panampullan
[2011-02-08 11:29:57]
[ android android-3.0-honeycomb ]
[ https://stackoverflow.com/questions/4932462/animate-the-transition-between-fragments ]

I'm trying to animate the transition between fragments. I got the answer from the following
Android Fragments and animation [1]

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

And my R.anim.slide_in_left

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

But when I tried this it showed

02-08 16:27:37.961: ERROR/AndroidRuntime(1717): FATAL EXCEPTION: main
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): java.lang.RuntimeException: Unknown animator name: translate
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:129)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:126)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:93)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:72)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.loadAnimator(FragmentManager.java:621)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:733)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.BackStackRecord.run(BackStackRecord.java:578)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1217)

Any ideas? When I checked Honeycomb API reference translate is there. What did I miss?
Is there any other way to animate the transition between fragments? Thank you

use ANIMATOR --- not Animation! use android.R.ANIMATOR.fade_in works, DON'T use android.R.ANIM.fade_in - it has behavior BUGS - StepanM
[+360] [2011-02-08 17:22:15] Roman Nurik [ACCEPTED]

You need to use the new android.animation framework (object animators) with FragmentTransaction.setCustomAnimations as well as FragmentTransaction.setTransition.

Here's an example on using setCustomAnimations from ApiDemos' FragmentHideShow.java:

ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

and here's the relevant animator XML from res/animator/fade_in.xml:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/accelerate_quad"
    android:valueFrom="0"
    android:valueTo="1"
    android:propertyName="alpha"
    android:duration="@android:integer/config_mediumAnimTime" />

Note that you can combine multiple animators using <set>, just as you could with the older animation framework.


EDIT: Since folks are asking about slide-in/slide-out, I'll comment on that here.

Slide-in and slide-out

You can of course animate the translationX, translationY, x, and y properties, but generally slides involve animating content to and from off-screen. As far as I know there aren't any transition properties that use relative values. However, this doesn't prevent you from writing them yourself. Remember that property animations simply require getter and setter methods on the objects you're animating (in this case views), so you can just create your own getXFraction and setXFraction methods on your view subclass, like this:

public class MyFrameLayout extends FrameLayout {
    ...
    public float getXFraction() {
        return getX() / getWidth(); // TODO: guard divide-by-zero
    }

    public void setXFraction(float xFraction) {
        // TODO: cache width
        final int width = getWidth();
        setX((width > 0) ? (xFraction * width) : -9999);
    }
    ...
}

Now you can animate the 'xFraction' property, like this:

res/animator/slide_in.xml:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:valueFrom="-1.0"
    android:valueTo="0"
    android:propertyName="xFraction"
    android:duration="@android:integer/config_mediumAnimTime" />

Note that if the object you're animating in isn't the same width as its parent, things won't look quite right, so you may need to tweak your property implementation to suit your use case.


(8) I got the fade_in and fade_out to work, but the others in /res/animator give errors. And none of those even appear to be for sliding in and sliding out. I've tried to write my own xml's to do this, but all I end up with is fragments on top of fragments. Some more help please? - Dave MacLean
And what about the translation ? How do you do a translation with values in percentage in a objectAnimator define in XML, please ? I didn't succeed in animate AdapterViewFlipper during flipping with vertical slide animations define in xml... - GBouerat
@DaveMacLean added note on slides. - Roman Nurik
(6) I'm getting 11-19 10:27:50.912: W/PropertyValuesHolder(23107): Method setXFraction() with type float not found on target class class android.widget.FrameLayout. But in my XML I have my custom view MyFrameLayout. Any ideas? - barkside
Using the new Animation framework only permits targetting ~30% of the devices out there, which, on commercial products, probably isn't acceptable. Yes, I realise there NineOldAndroids exists, but Google aren't providing their own support. Much like their design reliance on the ActionBar (with the only usable implementation provided by Jake Wharton). - James
to perfrom top_to_bottom animation check here stackoverflow.com/a/13582907/336990 - CoDe
(13) Actually, Roman, the advice should go the other way too: When using the Support Library, you need to use the old animation framework (android.R.anim) with FragmentTransaction.setCustomAnimations a.o. - pjv
I've added NineOldAndroids support to the Google Support library. See github.com/kedzie/Support_v4_NineOldAndroids for details. It allows using Property Animations for Fragment Transitions, PageTransformers, and some other stuff. - mark.kedzierski
It should also be noted that an implementation like this doesn't account for padding in the parent view. If the container that the fragments are animated within has padding, that presets the "x" property of the fragment view and has to be account for as the final "x" position of the animation destination...it can't just be zero all the time. - devunwired
@RomanNurik How would you suggest doing this with FragmentTransaction (non-support library). Would you have to return one of these custom views with getXFraction() in OnCreateView() in your fragment? - vinc3m1
I don't know why it happened, but I found that "xFraction" property name is not working. Instead of "xFraction", setting property name as "x" is working. - Sohyun Ahn
Just to add for the case of setting CustomAnimation on fragmentTransaction for 3.0+, you need to extend the parent Layout of your Fragment's view. For instance, if your fragment's root Layout is a RelativeLayout, you'll require to extend RelativeLayout and add getter setter for xFraction or any other property you want. Then it will apply to the fragment. - Achin Kumar
@SohyunAhn you need to declare a getter and a setter 'setXFraction' and 'getXFraction' on a view you animate - Boy
(1) @RomanNurik this answer worked great on most devices, but for some users (specifically on some Samsung Galaxy S3/4 phones) the width wasn't getting reported during the animations for some reason, causing the fragment to never appear. I was able to get it working for those users using an OnPredrawListener as shown here: mavyasoni9891.blogspot.com/2014/06/… - ajpolt
@RomanNurik how to use setCustomAnimation while making the FragA animating below the FragB? I know that zAdjustment only works for windows animation! Any workaround? - Muhammad Babar
@RomanNurik setXFraction should delay the execution until the layout is finished. On some devices (e.g. Xperia with activated STAMINA) the Fragment will not show up at all, because the animations are disabled. Here is my solution for this problem. - artkoenig
Is there a way to get the (default, native) transition animation between Activities and set it to fragments? If so, how? - android developer
1
[+207] [2015-11-30 06:25:05] Hiren Patel

I have done this way:

Add this method to replace fragments with Animations:

public void replaceFragmentWithAnimation(android.support.v4.app.Fragment fragment, String tag){
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
    transaction.replace(R.id.fragment_container, fragment);
    transaction.addToBackStack(tag);
    transaction.commit();
}

You have to add four animations in anim folder which is associate with resource:

enter_from_left.xml:

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

exit_to_right.xml:

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

enter_from_right.xml:

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

exit_to_left.xml:

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

Output:

enter image description here

Its Done.


(18) Great solution. However I am unsure why you swapped the directions to RTL. My method: .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right) - zed
(2) Awesome solution. Similar approach and the same animation files work for transitions between activities. - Stan
What directory to you put the xml files? I put in Layout but it does not work, I am new to Android. - Mike Zriel
(1) @MikeZriel, res -> anim -> put your xml here - Hiren Patel
(5) Thanks Hiren, I change the speed (700) to (300) far better and more like iOS - Mike Zriel
Hmm, this works fine on the emulator but is crazy slow/laggy on my s6 edge device... - Christer
Nvm, it was slow because I had the background image in the "drawable" folder and not in the "mipmap" folder :) - Christer
(1) Uhm. setCustomAnimations() expects resources of type animator, not anim. Attempting to use the above code as-is results in a runtime error: "Unknown animator name: translate" - Nathan Osman
Why this stuff gives me App Crash? I don't get any exception error message on android monitor.... why this happens only to me... - EvenBoy
@MaggiePhillips, post your crash log - Hiren Patel
(3) LOL, i came back with solution. I was importing android.app.fragment and FragmentManager on each java class. After checking some materials, I've found that using 'setCustomAnimations()' needs android.support.v4 library to be imported. important to say that should be 'support.v4.app' ! I replaced all the methods 'getFragmentManager()' with 'getSupportFragmentManager()', and all the import 'android.app.Fragment/FragmentManager...' to 'android.support.v4.app....', then this animation started to work well without crash... If you guys are stuck in similar cases, read my solution. Thx Hiren Patel xD - EvenBoy
(1) Animation is not working while creating Adapter classes. Any solution for this? - Nik
does it still show the animation when u press the back key/go back to previous fragment? - Jono
2
[+67] [2015-01-23 20:19:24] scorpiodawg

If you can afford to tie yourself to just Lollipop and later, this seems to do the trick:

import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.END));
f.setExitTransition(new Slide(Gravity.START));
getFragmentManager()
    .beginTransaction()
    .replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
    .commit();

Kotlin version:

f = MyFragment().apply {
    enterTransition = Slide(Gravity.END)
    exitTransition = Slide(Gravity.START)
}
fragmentManager
    .beginTransaction()
    .replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
    .commit();

Hope this helps.


(1) While that will achieve it on Lollipop, it's hardly practical as the percentage of device running Lollipop is negligible (currently 1.6% of Android devices are running Lollipop). - Eran Goldin
(1) new Slide(...) : call requires API level 21 - Chintan Soni
what getKey() stands for? - Alvaro
(16) @EranGoldin Nothing lasts forever.. would you scoff at an Android 2.0+ only solution today? - Tom
@Tom you have a point. However when your app has a large user base ou can't just bump the API level. If most of your users won't be able to run your app anymore after, that is no solution at all. - Eran Goldin
So simple and great answer. but what is implementation of getKey() method? - Chirag
@Chirag It's just a method that returns the fragment tag to identify it later. See: developer.android.com/reference/android/app/…, android.app.Fragment, java.lang.String) - scorpiodawg
(1) Works on API 16 like a charm by just using the support library. - fdermishin
(1) OMG! I cant believe I haven't use this before, it looks like it works with some physics! Much obliged @Scorpiodawg! - ZooMagic
This is the only one that I got working using androidx libraries. .setCustomAnimations does nothing. - The Berga
3
[+46] [2013-03-07 18:30:01] strangeluck

Nurik [1]'s answer was very helpful, but I couldn't get it to work until I found this [2]. In short, if you're using the compatibility library (eg SupportFragmentManager instead of FragmentManager), the syntax of the XML animation files will be different.

[1] https://stackoverflow.com/a/4936159/2050917
[2] https://stackoverflow.com/a/9856449/2050917

4
[+28] [2014-10-29 09:08:13] kirilv

Here's a slide in/out animation between fragments:

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();

We are using an objectAnimator.

Here are the two xml files in the animator subfolder.

enter_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
     <objectAnimator
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:duration="1000"
         android:propertyName="x"
         android:valueFrom="2000"
         android:valueTo="0"
         android:valueType="floatType" />
</set>

exit_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="-2000"
        android:valueType="floatType" />
</set>

I hope that would help someone.


(39) moving the view for 2000 px, is a very ugly solution. - carlo.marinangeli
(4) The exit_anim just "pops" off screen for me, it doesn't animate back across the screen. Any ideas? I am using .setCustomAnimations(R.animator.slide_in_left, R.animator.slide_out_right, R.animator.slide_in_left, R.animator.slide_out_right) - Mr Pablo
@MrPablo, the reason is probably that you haven't copy pasted the code above. setCustomAnimations should be called before the replace method. - Galya
In This case, If I replace other fragment with animation and I do minimize the app immediately before animation time-out or duration over and again come back to the application, it will display previous fragment and current fragment parallel. - Prince Dholakiya
5
[+25] [2017-02-12 22:14:55] Charlie

For anyone else who gets caught, ensure setCustomAnimations is called before the call to replace/add when building the transaction.


6
[+15] [2018-02-27 09:35:56] Gowthaman M

Try using this simple and fasted solution. Android provides some default animations.

fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

Output:

enter image description here


Woow.. this should be the accepted answer!! A simple and elegant solution. It's very smooth compared to the other suggests answers - Chathura Buddhika
7
[+12] [2013-04-20 03:17:26] sherpya

Android SDK implementation of FragmentTransaction wants an Animator while support library wants an Animation, don't ask me why but after strangeluk's comment I looked into android 4.0.3 code and support library. Android SDK uses loadAnimator() and support library uses loadAnimation()


8
[0] [2021-07-08 17:52:07] Bink

In an effort to add a more modern answer to this old question, if you've moved to Material Design, this can easily be done using the provided motion library--more details at https://material.io/develop/android/theming/motion.


9