วิธีการย้อนกลับภาพเคลื่อนไหว Fragment บน BackStack


114

ฉันคิดว่าระบบจะย้อนกลับภาพเคลื่อนไหวบนแบ็คสแต็คเมื่อกดปุ่มย้อนกลับเมื่อใช้ชิ้นส่วนโดยใช้รหัสต่อไปนี้:

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

คำตอบ:


266

ตามเอกสาร Android สำหรับภาพเคลื่อนไหวที่กำหนดเอง :

เปลี่ยนแปลง:

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

และตอนนี้ backstack เคลื่อนไหว - ในทางกลับกัน !!


2
btw ฉันรู้ว่าสิ่งนี้ไม่ได้เชื่อมโยงกับคำถามและคำตอบของคุณ แต่คุณอาจเชื่อมโยงฉันกับบางสิ่งที่อธิบาย customAnimations สักหน่อยได้ไหม : P
AreusAstarte

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

สวัสดีฉันใช้การเปลี่ยนเนื้อหาทำงานได้ดี แต่เมื่อฉันกดย้อนกลับและไปที่ส่วนก่อนหน้าพื้นหลังจะทำให้มุมมองเคลื่อนไหวไม่เคลื่อนไหว แต่ยังทับซ้อนกับส่วนที่เป็นอันตรายด้วยวิธีใดเพื่อหลีกเลี่ยงปัญหานี้
user3497504

23

ใช้แอนิเมชั่นที่ถูกต้องที่ฉันใช้ต่อไปนี้และมันทำงานได้อย่างมีเสน่ห์

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>

จากนั้นใช้การติดตามในขณะที่เพิ่มส่วน

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

และจะได้ผล 100%


2
โปรดทราบว่าสิ่งนี้จะไม่ทำงานหากคุณใช้ตัวจัดการส่วนการสนับสนุนหรือถ้าส่วนของคุณขยายเวอร์ชันการสนับสนุนของ Fragment
w3bshark

@ w3bshark จะทำให้ภาพเคลื่อนไหวดังกล่าวทำงานโดยใช้FragmentManagerและFragmentจากไลบรารีสนับสนุนได้อย่างไร
Daniel Shatz

2
@DanielShatz คุณต้องใช้การแปลมากกว่า objectAnimators ตัวอย่างเช่น slide_in_left.xml จะเป็น: <translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" />ดูคำตอบนี้: stackoverflow.com/a/5151774/1738090
w3bshark

1
ฉันกำลังลองสิ่งนี้ (บนอุปกรณ์ Marshmallow - ไม่ได้ลองรุ่นอื่น) มันไม่ทำงาน 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

ในกรณีของฉัน

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

จะสร้างภาพเคลื่อนไหวที่สมบูรณ์แบบ

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
ฉันคิดจะทำด้วยตัวเอง แต่ฉันขี้เกียจเกินไป และฉันบอกว่ามีใครบางคนควรโพสต์สิ่งนี้ใน StackOverflow และนี่คือ! ฮ่าฮ่า
F.Mysir

1
ไม่เคยมีใครโพสต์เรื่องนี้มาก่อนและฉันค่อนข้างเชื่อว่าถึงเวลาแล้วที่ฉันจะโพสต์คำตอบนี้เพื่อช่วยใครที่อาจอยู่ในรองเท้าเดียวกันกับฉัน ... 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)

แทนที่ด้านบนด้วย:

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
ฉันอยากจะแนะนำให้คุณเพิ่มคำอธิบายว่าคำแนะนำของคุณช่วยได้อย่างไร
Wtower

2
ฉันไม่รู้ว่าทำไมมันถึงใช้งานได้ (: แต่เมื่อเพิ่มแอนิเมชั่นหลังจากนั้นreplaceและaddToBackstackไม่ทำงาน
TarikW

3
@TarikW ฉันช้าไปหน่อย แต่คำสั่งซื้อมีความสำคัญในเรื่องนี้คุณต้องเรียก setCostomAnimations ก่อนแทนที่เมธอด addToBackStack
MD Husnain Tahir

1

ตามที่กล่าวไว้ในคลาส 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);

ในที่สุดคุณก็สามารถใช้วิธีนี้ได้

 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

งานนี้ผม !! รหัสนี้สำหรับชิ้นส่วน! หากต้องการใช้รหัสนี้ในกิจกรรมให้ลบที่จุดเริ่มต้น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();

ขอให้โชคดี !!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.