Come invertire le animazioni dei frammenti su BackStack?


114

Pensavo che il sistema avrebbe invertito le animazioni sul backstack quando si preme il pulsante Indietro quando si utilizzano frammenti utilizzando il codice seguente:

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

Risposte:


266

Secondo la documentazione di Android per l'animazione personalizzata :

Modificare:

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

Per:

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

e ora il backstack si anima - Al contrario !!


2
a proposito, so che questo non è collegato alla tua domanda e risposta, ma potresti forse collegarmi a qualcosa che spiega un po 'le animazioni personalizzate? : P
AreusAstarte

2
AreusAstarte: vedi developer.android.com/reference/android/app/… , int, int, int)
mDroidd

Ciao sto effettivamente usando la Transizione del contenuto, funziona bene, ma quando premo Indietro e vado al frammento precedente lo sfondo scompare semplicemente animando le viste ma anche sovrastando quelle precedenti, qualche modo per evitarlo?
user3497504

23

Usa l'animazione corretta che ho usato quanto segue e funziona a meraviglia

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>

Quindi usa quanto segue mentre aggiungi frammento

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

e funzionerà al 100%


2
Nota che questo non funzionerà se stai usando il gestore dei frammenti di supporto o se il tuo frammento estende la versione di supporto di Fragment
w3bshark

@ w3bshark Come far funzionare tali animazioni utilizzando FragmentManagere Fragmentdalla libreria di supporto?
Daniel Shatz

2
@DanielShatz Devi usare le traduzioni invece di objectAnimators. Per esempio, slide_in_left.xml sarebbe: <translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" />Vedere questa risposta: stackoverflow.com/a/5151774/1738090
w3bshark

1
Lo sto provando (sul dispositivo Marshmallow - non ho provato altre versioni). Non funziona. final FragmentTransaction 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

nel mio 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);

creerebbe un'animazione perfetta.

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>

1
Ho pensato di farlo da solo, ma sono troppo pigro. E ho detto che qualcuno avrebbe dovuto postarlo su StackOverflow ed eccolo qui! haha
F.Mysir

1
Nessuno l'aveva pubblicato prima e credevo che fosse il mio turno di pubblicare questa risposta, per aiutare chi potrebbe essere nei miei stessi panni ... 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)

Sostituisci quanto sopra 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();

1
Ti consiglierei di aggiungere una spiegazione su come la tua raccomandazione aiuta.
Wtower

2
Non so perché funzioni (:, ma quando viene aggiunta l'animazione dopo replacee addToBackstack, non funziona
TarikW

2
@TarikW sono un po 'in ritardo, ma l'ordine è importante in questo, devi chiamare setCostomAnimations prima di sostituire, metodi addToBackStack
MD Husnain Tahir

1

Questo è come menzionato nella 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);

quindi finalmente puoi usare un metodo come questo

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

0

questo lavoro per me !! questo codice per frammento! se vuoi usare questo codice in attività, cancellalo all'inizio 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();

Buona fortuna a te!!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.