Comment inverser les animations de fragments sur BackStack?

114

Je pensais que le système inverserait les animations sur la pile d'arrière-plan lorsque le bouton de retour était enfoncé lors de l'utilisation de fragments en utilisant le code suivant:

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out);
ft.replace(R.id.viewContainer, new class(), "layout").addToBackStack(null).commit();

la source

Réponses:

266

Selon la documentation Android pour l'animation personnalisée :

Changement:

ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out);

À:

ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out, R.anim.hyperspace_in, R.anim.slide_out );

et maintenant la backstack s'anime - En sens inverse !!


la source
2
btw, je sais que cela n'est pas lié à votre question et réponse, mais pourriez-vous peut-être me relier à quelque chose qui explique un peu customAnimations? : P
AreusAstarte
2
AreusAstarte: voir developer.android.com/reference/android/app/… , int, int, int)
mDroidd
Salut, j'utilise réellement la transition de contenu, cela fonctionne bien, mais lorsque j'appuie sur le dos et que je reviens au fragment précédent, l'arrière-plan disparaît simplement en animant les vues mais également en se superposant aux vues précédentes, comment éviter cela?
user3497504
23

Utilisez l'animation correcte J'ai utilisé ce qui suit et cela fonctionne comme un charme

slide_in_left.xml

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

slide_in_right.xml

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

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="1000"
        android:valueType="floatType" />

</set>

slide_out_left.xml

   <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime" >

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="-1000"
        android:valueType="floatType" />

</set>

slide_out_right.xml

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

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="-1000"
        android:valueTo="0"
        android:valueType="floatType" />

</set>

Ensuite, utilisez ce qui suit lors de l'ajout d'un fragment

setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left,
                                R.anim.slide_out_right, R.anim.slide_in_right)

et cela fonctionnera à 100%

Aniket
la source
2
Notez que cela ne fonctionnera pas si vous utilisez le gestionnaire de fragments de support ou si votre fragment étend la version de support de Fragment
w3bshark
@ w3bshark Comment faire fonctionner ces animations en utilisant FragmentManageret Fragmentdepuis la bibliothèque de support?
Daniel Shatz
2
@DanielShatz Vous devez utiliser des traductions plutôt que des objectAnimators. Par exemple, slide_in_left.xml serait: <translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" />Voir cette réponse: stackoverflow.com/a/5151774/1738090
w3bshark
1
J'essaye ceci (sur l'appareil Marshmallow - je n'ai pas essayé d'autres versions). Ça ne marche pas. FragmentTransaction finale fragmentTransaction = getFragmentManager (). beginTransaction (); fragmentTransaction.setCustomAnimations (R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); fragmentTransaction.replace (R.id.fl_right_container, detailFragment); fragmentTransaction.replace (R.id.fl_left_container, subcategoriesFragment, TestActivity.TAG_SUBCATEGORIES_FRAGMENT); fragmentTransaction.commit ();
techtinkerer
13

dans mon cas

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

créerait une animation parfaite.

slide_in_right

<?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>

slide_out_left

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="-50%p"
               android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
           android:duration="@android:integer/config_mediumAnimTime" />
</set>
Hoang Nguyen Huu
la source
1
J'ai pensé à le faire moi-même, mais je suis trop paresseux. Et j'ai dit que quelqu'un aurait dû poster ceci sur StackOverflow et le voici! haha
F.Mysir
1
Personne n'avait posté cela auparavant et je croyais bien que c'était à mon tour de poster cette réponse, pour aider à qui pourrait être dans la même situation que moi ... lol @ F.Mysir
Hoang Nguyen Huu
3
.setCustomAnimations(R.animator.fragment_fade_in,
        R.animator.fragment_fade_out,
        R.animator.fragment_fade_p_in,
        R.animator.fragment_fade_p_out)

Remplacez ce qui précède par:

mFragmentManager.beginTransaction()
    .setCustomAnimations(R.animator.fragment_fade_in,
            R.animator.fragment_fade_out,
            R.animator.fragment_fade_p_in,
            R.animator.fragment_fade_p_out)
    .replace(R.id.main_container, FragmentPlayerInfo.getInstance(data))
    .addToBackStack(FragmentPlayerInfo.TAG)
    .commit();
TarikW
la source
1
Je vous recommanderais d'ajouter une explication sur la façon dont votre recommandation aide.
Wtower
2
Je ne sais pas pourquoi cela fonctionne (:, mais une fois ajouté une animation après replaceet addToBackstack, ne fonctionne pas
TarikW
2
@TarikW Je suis un peu en retard, mais l'ordre est important dans ce domaine, vous devez appeler setCostomAnimations avant de remplacer, méthodes addToBackStack
MD Husnain Tahir
1

C'est comme mentionné dans la classe Fragment Transaction.

/**
     * Set specific animation resources to run for the fragments that are
     * entering and exiting in this transaction. The <code>popEnter</code>
     * and <code>popExit</code> animations will be played for enter/exit
     * operations specifically when popping the back stack.
     *
     * @param enter An animation or animator resource ID used for the enter animation on the
     *              view of the fragment being added or attached.
     * @param exit An animation or animator resource ID used for the exit animation on the
     *             view of the fragment being removed or detached.
     * @param popEnter An animation or animator resource ID used for the enter animation on the
     *                 view of the fragment being readded or reattached caused by
     *                 {@link FragmentManager#popBackStack()} or similar methods.
     * @param popExit An animation or animator resource ID used for the enter animation on the
     *                view of the fragment being removed or detached caused by
     *                {@link FragmentManager#popBackStack()} or similar methods.
     */
    @NonNull
    public abstract FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int enter,
            @AnimatorRes @AnimRes int exit, @AnimatorRes @AnimRes int popEnter,
            @AnimatorRes @AnimRes int popExit);

alors enfin vous pouvez utiliser une méthode comme celle-ci

 mFragmentManager.beginTransaction()
                        .replace(R.id.container, fragment)
                        .setCustomAnimations(R.anim.slide_left,//enter
                                             R.anim.slide_out_left,//exit
                                             R.anim.slide_right,//popEnter
                                             R.anim.slide_out_right)//popExit
                        .addToBackStack(fragment.toString())
                        .commit();
Islam Alshnawey
la source
0

ce travail pour moi !! ce code pour fragment! si vous souhaitez utiliser ce code en activité, supprimez au début getActivity()!!

getActivity().getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.fade_out,android.R.anim.slide_in_left, android.R.anim.fade_out)
        .replace(R.id.fragment_container, new YourFragment)
        .addToBackStack(null)
        .commit();

Bonne chance à toi!!

MODERNE
la source