Je veux animer la suppression de fragment.
J'ai essayé:
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.Push_down_in, R.anim.Push_up_out)
.remove(myFragment)
.commit();
mais le fragment disparaît tout simplement.
J'ai remarqué que l'animation sort uniquement avec 'replace', alors j'ai essayé de remplacer le fragment par un fragment vide comme ceci:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.Push_down_in, R.anim.Push_up_out)
.replace(viewId, new Fragment())
.commit();
Mais il ne fait que disparaître, disparaît.
Alors, comment puis-je animer la suppression de fragment?
Je l'ai compris.
La vue sortante est animée sur la toile de la vue entrante. Ainsi, s'il n'y a pas de toile entrante, il n'y a pas de toile pour l'animation.
Pour afficher l'animation, je devais toujours utiliser remplacer et utiliser des fragments entrants de la même taille que ceux qui existaient déjà. Une fois l'animation terminée, je règle l'affichage des nouveaux fragments.
J'ai vu cela quand j'avais des problèmes similaires et je pensais juste que Id laisserais tomber une note rapide.
Plutôt que de créer un fragment factice afin de remplacer celui qui existe, je pense que vous devriez animer la vue des fragments en cours. Lorsque l'animation est terminée, vous pouvez simplement supprimer le fragment.
Voici comment je l'ai fait:
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);
}
Vous pouvez animer la suppression en définissant cette animation personnalisée sur fragmentTransaction.
fragmentTransaction.setCustomAnimations(R.anim.right_in, R.anim.defff,R.anim.defff,R.anim.right_out);
Les troisième et quatrième paramètres servent à enlever le fragment
Remplacer par un fragment vide, avant le point d'insertion du fragment suivant et retarder l'insertion du fragment suivant (de 200 ms) afin que l'animation de sortie du fragment vierge puisse jouer, a résolu mon problème.
C'est le code pour insérer un fragment vide avec une animation de sortie.
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>
raison comme @hugoc a dit
La vue sortante est animée sur la toile de la vue entrante. Ainsi, s'il n'y a pas de toile entrante, il n'y a pas de toile pour l'animation.
Pour afficher l'animation, je devais toujours utiliser remplacer et utiliser des fragments entrants de la même taille que ceux qui existaient déjà. Une fois l'animation terminée, je règle l'affichage des nouveaux fragments.
ci-dessous est le code actuel:
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();
Je suis d'accord avec hugoc et voici un codepour le résoudre
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);
}
}
}
}
Je me suis inspiré de la réponse de Zoltish, voici mon implémentation:
1.ajoutez cette méthode à l’intérieur du fragment, cela animera le fragment hors de l’écran à gauche:
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);
}
La méthode à l'intérieur de onAnimationEnd () supprime le fragment comme ceci:
getSupportFragmentManager().beginTransaction().
remove(getSupportFragmentManager().findFragmentById(R.id.fragment_container)).commit();
2.call l'animateOut du fragment de onBack () de l'activité.
À votre santé
À propos, mon getDensity () est:
public static int getDensity(Context context)
{
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int)metrics.density;
}
avec lui, je calcule la valeur DP pour le périphérique en cours d’exécution.
Donc le moyen le plus simple:
Lorsque vous ouvrez un fragment (appelé de l'activité parent):
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();
Spécifiez les transactions d'entrée et de sortie
transaction.setCustomAnimations (R.anim.slide_up, R.anim.slide_down);
Lors de la fermeture d'un fragment (appelé de l'intérieur du fragment)
getActivity().getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_up, R.anim.slide_down).remove(this).commit();
Spécifiez les transactions d'entrée et de sortie
setCustomAnimations (R.anim.slide_up, R.anim.slide_down)
setCustomAnimations (entrée, sortie, popEnter, popExit) support entrée et sortie de l'animation, définissez donc quatre animations et vous devez la conserver avant 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()
1-Call animate sur fragment.getView ().
2-Supprimer le fragment à l'intérieur de 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();
Ce qui entre:
c'est un nouveau fragment qui doit être montré
Quelle sortie:
c'est le fragment en cours qu'il faut cacher
Qu'est-ce que popEnter:
c'est le fragment précédent qui doit être montré
Quel popExit:
c'est le fragment en cours qu'il faut cacher
Pour utiliser ces animations, vous devez les cibler sur les commandes d’affichage ou de masquage des transactions. Les animations de sortie ne fonctionnent pas avec les procédures de suppression/remplacement.