¿Cómo invertir animaciones de fragmentos en BackStack?

114

Pensé que el sistema revertiría las animaciones en el backstack cuando se presiona el botón Atrás al usar fragmentos usando el siguiente código:

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();

fuente

Respuestas:

266

Según la documentación de Android para animación personalizada :

Cambio:

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

A:

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

y ahora el backstack se anima - ¡¡Al revés !!


fuente
2
Por cierto, sé que esto no está relacionado con tu pregunta y respuesta, pero ¿podrías vincularme a algo que explique un poco las animaciones personalizadas? : P
AreusAstarte
2
AreusAstarte: consulte developer.android.com/reference/android/app/… , int, int, int)
mDroidd
Hola, estoy usando Transición de contenido, está funcionando bien, pero cuando presiono hacia atrás y voy al fragmento anterior, el fondo simplemente desaparece animando las vistas pero también superponiéndose con las anteriores, ¿alguna forma de evitar esto?
user3497504
23

Use la animación correcta He usado lo siguiente y está funcionando como un encanto

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>

Luego use lo siguiente mientras agrega un fragmento

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

y funcionará al 100%

Aniket
fuente
2
Tenga en cuenta que esto no funcionará si está utilizando el administrador de fragmentos de soporte o si su fragmento extiende la versión de soporte de Fragment
w3bshark
@ w3bshark ¿Cómo hacer que estas animaciones funcionen usando FragmentManagery Fragmentdesde la biblioteca de soporte?
Daniel Shatz
2
@DanielShatz Debes usar traducciones en lugar de objectAnimators. Por ejemplo, slide_in_left.xml sería: <translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" />Vea esta respuesta: stackoverflow.com/a/5151774/1738090
w3bshark
1
Estoy probando esto (en el dispositivo Marshmallow, no probé otras versiones). No funciona. FragmentTransaction final 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

en mi caso

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

crearía una animación perfecta.

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
fuente
1
Pensé en hacerlo yo mismo, pero soy demasiado vago. ¡Y dije que alguien debería haber publicado esto en StackOverflow y aquí está! jaja
F.Mysir
1
Nadie había publicado esto antes y creía que era mi turno de publicar esta respuesta, para ayudar a quién podría estar en los mismos zapatos que yo ... 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)

Reemplaza lo anterior con:

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
fuente
1
Le recomendaría que agregue una explicación sobre cómo ayuda su recomendación.
Wtower
2
No sé por qué funciona (:, pero cuando se agrega animación después de replacey addToBackstack, no funciona
TarikW
2
@TarikW llego un poco tarde, pero el orden es importante en esto, debe llamar a setCostomAnimations antes de reemplazar, métodos addToBackStack
MD Husnain Tahir
1

Esto es como se menciona en la clase 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);

así que finalmente puedes usar un método como este

 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
fuente
0

este trabajo para mi !! este código para el fragmento! Si desea utilizar este código en la actividad, eliminar al principio 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();

¡¡Buena suerte para ti!!

MODERNO
fuente