Android: la animación personalizada en la transacción de fragmentos no se está ejecutando

83

Estoy usando Google API 8 (Android 2.2) con el paquete de soporte v4.

No da ningún error ni animación.

Transacción:

FragmentTransaction transaction = manager.beginTransaction();       
transaction.replace(R.id.content, myFragment);
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.commit();

Animaciones:

slide_in_left.xml

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

slide_out_right.xml

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

¿Alguien sabe lo que está pasando aquí?

adheus
fuente
1
Los fragmentos no se introdujeron hasta Honeycomb (API 11, Android 3.0). Ese podría ser el problema, pero hubiera pensado que Eclipse te lo diría.
Steve Blackwell
6
Por eso estoy usando el paquete de soporte.
adheus

Respuestas:

256

El administrador estaba apilando mi transacción antes de que estableciera la animación, por lo que apila la transacción sin animaciones (triste pero cierto), y eso ocurre incluso si realizo la transacción después del setCustomAnimations().

La solución es configurar las animaciones primero:

FragmentTransaction transaction = manager.beginTransaction();       
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.replace(R.id.content, myFragment);
transaction.commit();
adheus
fuente
por lo que debe dividir la declaración evitando el truco del objeto devuelto por sí mismo
sherpya
4
transaction.something().somethingelse().replace().commit(), muchos de los métodos de Android regresan thispara que pueda evitar volver a escribir la variable, pero de alguna manera aquí expone un efecto secundario y setCustomAnimations()debe llamarse por separado
sherpya
44
Solo para tener en cuenta, el "truco de objeto devuelto automáticamente" se llama "encadenamiento de métodos"
Egor
El método de encadenamiento de la llamada anterior definitivamente funciona. Solo lo probé en mi propio proyecto.
MawrCoffeePls
Para obtener más información, para animar el fragmento cuando salga de la pila posterior, use transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right, R.anim.slide_in_left, R.anim.slide_out_right);en su lugar.
Justin
23

Como se sugirió anteriormente, las declaraciones separadas definitivamente funcionarán. Pero el truco aquí es setCustomAnimationantes de configurar el tipo de transacción a saber. add, replaceetc. de lo contrario, no lo hará. Entonces, aplicar la misma lógica method chainingtambién funciona. p.ej.

getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations(R.anim.a_slide_up,
                             R.anim.a_slide_down,
                             R.anim.a_slide_up,
                             R.anim.a_slide_down)
        .add(R.id.root_layout, 
             MyFrag.newInstance())
        .addToBackStack("MyFrag")
        .commit();

Poniéndolo aquí, para que alguien que lo prefiera lo method chainingencuentre útil. ¡Salud!

Harisewak
fuente
1
Estoy un poco ofendido por la forma en que usa el operador 'punto' para el encadenamiento de métodos.
Shaishav
1
De acuerdo @Shaishav, escribió esta respuesta hace dos años, actualizándola .. ¡Gracias!
Harisewak
7

Dejando esto aquí porque es la pregunta más popular. Tuve el mismo problema con la transacción de fragmentos que no se animaba. El culpable fue tener el atributo android:animateLayoutChangesestablecido en trueen el diseño contenedor.

Espero que ayude a alguien a ahorrar algo de tiempo en la búsqueda de una solución, ya que puede ser difícil de notar cuando se tienen diseños anidados en diferentes archivos.

Màrius Mora Bosch
fuente
La animación funciona ahora, pero hay un nuevo problema: se ha cambiado el comportamiento de la animación. antes de que se deslice horizontalmente (como se esperaba). ahora expandiéndose desde la esquina
Sharad Kale
0

Otra razón puede ser colocar innecesariamente fragmentTransaction.show()antes del compromiso. Esto hace que las transiciones emergentes no se muestren en algunas versiones de API de Android.

Carson Holzheimer
fuente