Jak odwrócić animacje fragmentów w BackStack?


114

Myślałem, że system odwróci animacje na backstacku, gdy przycisk Wstecz zostanie naciśnięty podczas korzystania z fragmentów przy użyciu następującego kodu:

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

Odpowiedzi:


266

Zgodnie z dokumentacją Androida dotyczącą niestandardowej animacji :

Zmiana:

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

Do:

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

a teraz backstack ożywia się - w odwrotnej kolejności !!


2
btw, wiem, że to nie jest związane z twoim pytaniem i odpowiedzią, ale czy możesz połączyć mnie z czymś, co wyjaśnia trochę CustomAnimations? : P
AreusAstarte

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

Cześć, aktualnie używam przejścia treści, działa dobrze, ale kiedy wciskam wstecz i przechodzę do poprzedniego fragmentu, tło po prostu znika, animując widoki, ale także nakładając się na poprzednie, czy jest jakiś sposób, aby tego uniknąć?
user3497504

23

Użyj animacji poprawnej, której użyłem poniżej, i działa jak urok

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>

Następnie użyj następujących podczas dodawania fragmentu

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

i będzie działać w 100%


2
Zauważ, że to nie zadziała, jeśli używasz menedżera fragmentów wsparcia lub jeśli twój fragment rozszerza wersję wsparcia fragmentu
w3bshark

@ w3bshark Jak sprawić, by takie animacje działały przy użyciu FragmentManageri Fragmentz biblioteki wsparcia?
Daniel Shatz

2
@DanielShatz Musisz używać tłumaczeń zamiast animatorów obiektów. Na przykład slide_in_left.xml będzie wyglądał następująco: <translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" />Zobacz tę odpowiedź: stackoverflow.com/a/5151774/1738090
w3bshark

1
Wypróbowuję to (na urządzeniu Marshmallow - nie próbowałem innych wersji). To nie działa. 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

w moim przypadku

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

stworzy doskonałą animację.

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
Myślałem o zrobieniu tego samodzielnie, ale jestem zbyt leniwy. I powiedziałem, że ktoś powinien był opublikować to na StackOverflow i oto jest! haha
F.Mysir

1
Nikt tego wcześniej nie opublikował i całkiem wierzyłem, że nadeszła moja kolej, aby opublikować tę odpowiedź, aby pomóc, więc kto może być w tym samym miejscu co ja ... 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)

Zamień powyższe na:

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
Radziłbym dodać wyjaśnienie, w jaki sposób pomaga twoja rekomendacja.
Wtower

2
Nie wiem, dlaczego to pracę (:, ale po dodaniu animacji po replacei addToBackstacknie poddaje się obróbce
TarikW

2
@TarikW Trochę się spóźniam, ale kolejność jest w tym ważna, przed wymianą trzeba wywołać setCostomAnimations, metody addToBackStack
MD Husnain Tahir

1

Jest to wspomniane w klasie transakcji fragmentarycznych.

/**
     * 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);

więc w końcu możesz użyć takiej metody

 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

ta praca dla mnie !! ten kod dla fragmentu! jeśli chcesz użyć tego kodu w działaniu, usuń na początku 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();

Powodzenia!!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.