可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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.
回答2:
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);
}
回答3:
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
回答4:
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>
回答5:
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.
回答6:
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:
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);
}
}
}
}
回答8:
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.
回答9:
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();
回答10:
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()
回答11:
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)