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条回答
干净又极端
2楼-- · 2019-02-01 18:41

What enter:
it is new fragment which must be show

What exit:
it is current fragment which must be hide

What popEnter:
it is previous fragment which must be show

What popExit:
it is current fragment which must be hide

For use these animations, you should target them on show or hide transaction commands. Exit animations doesn't work on remove/replace procedures.

查看更多
甜甜的少女心
3楼-- · 2019-02-01 18:42

I agreed with hugoc and here some code to solve it

public class MyActivity extends Activity {
    //Some thing
    public void Fragment2BackToFragment1(Fragment fragment1, Fragment fragment2) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        animateExit(fragment2);
        ft.replace(R.id.main_content, fragment1, "fragment1");
        ft.commit();
    }
    private void animateExit(Fragment exitFragment) {
        if (exitFragment != null) {
            final View view = exitFragment.getView();
            if (view != null) {
                int anim = R.anim.fade_out;
                Animation animation =
                    AnimationUtils.loadAnimation(getActivity(), anim);
                animation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        view.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                view.setVisibility(View.GONE);
                            }
                        }, 300);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {


                    }
                });
                view.startAnimation(animation);
            }
        }
    }
}
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-02-01 18:42

An easy fix below:

1-Call animate on fragment.getView().

2-Remove fragment inside onAnimationEnd().

final Fragment frag= getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
        frag.getView().animate().alpha(0f).scaleX(0f).scaleY(0f)

                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        getSupportFragmentManager()
                                .beginTransaction()
                                .remove(frag)
                                .commit();
                    }
                }).start();
查看更多
虎瘦雄心在
5楼-- · 2019-02-01 18:43

I figured it out.

The exiting view is animated on the canvas of the entering view so if there is no entering canvas there is no canvas for the animation.

To show the animation I had to always use replace and use entering fragments of the same size to those exiting. After the animation is finished I set the view of the new fragments to gone.

查看更多
甜甜的少女心
6楼-- · 2019-02-01 18:46

reason as @hugoc said

The exiting view is animated on the canvas of the entering view so if there is no entering canvas there is no canvas for the animation.

To show the animation I had to always use replace and use entering fragments of the same size to those exiting. After the animation is finished I set the view of the new fragments to gone.

below is actual code:

FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.setCustomAnimations(R.anim.slide_in_bottom, R.anim.slide_out_top);
    transaction.hide(removeFragment).add(R.id.fragment_container,addFragment).commit();
    transaction = manager.beginTransaction();
    transaction.remove(removeFragment).commit();
查看更多
等我变得足够好
7楼-- · 2019-02-01 18:53

You could animate the removal by setting this custom animation to the fragmentTransaction

        fragmentTransaction.setCustomAnimations(R.anim.right_in, R.anim.defff,R.anim.defff,R.anim.right_out);

The third and fourth params are for removing the fragment

查看更多
登录 后发表回答