How to animate fragment removal

2019-02-01 18:37发布

I want to animate the removal of fragment.

I tried:

getSupportFragmentManager().beginTransaction()
    .setCustomAnimations(R.anim.push_down_in, R.anim.push_up_out)
    .remove(myFragment)
    .commit();

but the fragment just disappears.

I noticed the out animation only plays with 'replace', so I tried to replace the fragment with an empty Fragment like this:

getSupportFragmentManager()
    .beginTransaction()
    .setCustomAnimations(R.anim.push_down_in, R.anim.push_up_out)
    .replace(viewId, new Fragment())
.commit();

But it still just disappears disappears.

So, how can I animate the removal of fragment?

11条回答
小情绪 Triste *
2楼-- · 2019-02-01 18:58

setCustomAnimations(enter, exit, popEnter, popExit) support enter and exit animation, So set four animations and must keep it before transaction.replace()

Kotlin:

    val manager = supportFragmentManager
    val transaction = manager.beginTransaction()
    transaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right ,
            android.R.anim.slide_in_left, android.R.anim.slide_out_right)
    transaction.commit()
查看更多
女痞
3楼-- · 2019-02-01 18:59

Replacing with an empty fragment, before the point of insertion of the next fragment and also delaying the insertion of the next fragment (by 200ms) so that the exit animation of the blank fragment can play, solved my problem.

This the code to insert an empty fragment with exit animation.

getSupportFragmentManager()
                        .beginTransaction()
                        .setCustomAnimations(R.anim.exit, R.anim.pop_exit)
                        .replace(R.id.fragmentLayout, new Fragment())
                        .commit();

Exit.xml

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

</set>

pop_exit.xml

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

</set>
查看更多
Viruses.
4楼-- · 2019-02-01 18:59

So the easy way:

When you open a fragment (called from parent Activity):

    FragmentA fragment = new FragmentA();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setCustomAnimations(R.anim.slide_up, R.anim.slide_down);
    transaction.add(android.R.id.content, fragment);
    transaction.addToBackStack(null);
    transaction.commit();

Specify enter and exit transactions

transaction.setCustomAnimations(R.anim.slide_up, R.anim.slide_down);

When closing a fragment (called from inside the fragment)

getActivity().getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_up, R.anim.slide_down).remove(this).commit();

Specify enter and exit transactions

setCustomAnimations(R.anim.slide_up, R.anim.slide_down)

查看更多
萌系小妹纸
5楼-- · 2019-02-01 19:08

I saw this when I was having similar problems and just thought Id drop a quick note.

Rather than creating a dummy fragment in order to replace the existing one I think you should animate the current fragments view. When the animation finishes you can simply remove the fragment.

This is how i did it:

final FragmentActivity a = getSherlockActivity();

if (a != null) {
    //Your animation
    Animation animation = AnimationUtils.loadAnimation(a, R.anim.bottom_out);
    animation.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime));

    //You can use AnimationListener, MagicAnimationListener is simply a class extending it.
    animation.setAnimationListener(new MagicAnimationListener() {
        @Override
        public void onAnimationEnd(Animation animation) {
            //This is the key, when the animation is finished, remove the fragment.
            try {
                FragmentTransaction ft = a.getSupportFragmentManager().beginTransaction();
                ft.remove(RestTimerFragment.this);
                ft.commitAllowingStateLoss();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    //Start the animation.  
    getView().startAnimation(animation);
}
查看更多
ゆ 、 Hurt°
6楼-- · 2019-02-01 19:08

I got inspiration from Zoltish answer , this is my implementation:

1.add this method inside the fragment , it will animate the fragment out of the screen to the left:

public void animateOut()
{
    TranslateAnimation trans=new TranslateAnimation(0,-300*Utils.getDensity(getActivity()), 0,0);
    trans.setDuration(150);
    trans.setAnimationListener(new Animation.AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            ((BetsActivty)getActivity()).removeFrontFragmentAndSetControllToBetting();
        }
    });
    getView().startAnimation(trans);
}

The method that inside onAnimationEnd() removes the fragment like this:

getSupportFragmentManager().beginTransaction().
        remove(getSupportFragmentManager().findFragmentById(R.id.fragment_container)).commit();

2.call the animateOut of the fragment from onBack() of the activity.

Cheers

by the way my getDensity() is:

public static int getDensity(Context context)
{
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return (int)metrics.density;
}

with it i calculate the DP value for the current running Device.

查看更多
登录 后发表回答