web-dev-qa-db-fra.com

Animer la transition entre les fragments

J'essaye d'animer la transition entre les fragments. J'ai eu la réponse de ce qui suit
Fragments et animation Android

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

Et mon R.anim.slide_in_left

<?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>

Mais quand j'ai essayé ça, ça a montré

02-08 16:27:37.961: ERROR/AndroidRuntime(1717): FATAL EXCEPTION: main
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): Java.lang.RuntimeException: Unknown animator name: translate
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.Java:129)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.Java:126)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.Java:93)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.Java:72)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.app.FragmentManagerImpl.loadAnimator(FragmentManager.Java:621)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:733)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:919)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.app.BackStackRecord.run(BackStackRecord.Java:578)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at Android.app.FragmentManagerImpl.execPendingActions(FragmentManager.Java:1217)

Des idées? Lorsque j'ai vérifié la référence d'API Honeycomb, translate est là. Qu'est-ce que j'ai raté?
Existe-t-il un autre moyen d’animer la transition entre fragments? Je vous remercie

268
Labeeb Panampullan

Vous devez utiliser le nouveau cadre Android.animation (animateurs d'objets) avec FragmentTransaction.setCustomAnimations ainsi que FragmentTransaction.setTransition.

Voici un exemple d'utilisation de setCustomAnimations de ApiDemos ' FragmentHideShow.Java :

ft.setCustomAnimations(Android.R.animator.fade_in, Android.R.animator.fade_out);

et voici le code XML d'animateur pertinent de res/animator/fade_in.xml :

<objectAnimator xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:interpolator="@Android:interpolator/accelerate_quad"
    Android:valueFrom="0"
    Android:valueTo="1"
    Android:propertyName="alpha"
    Android:duration="@Android:integer/config_mediumAnimTime" />

Notez que vous pouvez combiner plusieurs animateurs à l'aide de <set>, comme vous le feriez avec l'ancien framework d'animation.


EDIT: Étant donné que les gens se posent des questions sur l'insertion/extraction, je vais en parler ici.

Slide-in et slide-out

Vous pouvez bien sûr animer les propriétés translationX, translationY, x et y, mais généralement, les diapositives impliquent une animation du contenu vers et hors écran. Autant que je sache, aucune propriété de transition n'utilise des valeurs relatives. Cependant, cela ne vous empêche pas de les écrire vous-même. N'oubliez pas que les animations de propriété nécessitent simplement des méthodes de lecture et de définition pour les objets que vous animez (dans ce cas, les vues), de sorte que vous pouvez simplement créer votre propre getXFraction et setXFraction méthodes de votre sous-classe de vue, comme ceci:

public class MyFrameLayout extends FrameLayout {
    ...
    public float getXFraction() {
        return getX() / getWidth(); // TODO: guard divide-by-zero
    }

    public void setXFraction(float xFraction) {
        // TODO: cache width
        final int width = getWidth();
        setX((width > 0) ? (xFraction * width) : -9999);
    }
    ...
}

Maintenant, vous pouvez animer la propriété 'xFraction', comme ceci:

res/animator/slide_in.xml :

<objectAnimator xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:interpolator="@Android:anim/linear_interpolator"
    Android:valueFrom="-1.0"
    Android:valueTo="0"
    Android:propertyName="xFraction"
    Android:duration="@Android:integer/config_mediumAnimTime" />

Notez que si l'objet dans lequel vous animez n'est pas de la même largeur que son parent, les choses ne se présenteront pas comme prévu. Vous devrez peut-être ajuster la mise en œuvre de votre propriété pour l'adapter à votre cas d'utilisation.

338
Roman Nurik

J'ai fait comme ça:

Ajouter cette méthode à remplacer les fragments par Animations :

public void replaceFragmentWithAnimation(Android.support.v4.app.Fragment fragment, String tag){
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
    transaction.replace(R.id.fragment_container, fragment);
    transaction.addToBackStack(tag);
    transaction.commit();
}

Vous devez ajouter quatre animations dans anim dossier qui est associé à ressource :

enter_from_left.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shareInterpolator="false">
    <translate
        Android:fromXDelta="-100%" Android:toXDelta="0%"
        Android:fromYDelta="0%" Android:toYDelta="0%"
        Android:duration="700"/>
</set>

exit_to_right.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shareInterpolator="false">
    <translate
        Android:fromXDelta="0%" Android:toXDelta="100%"
        Android:fromYDelta="0%" Android:toYDelta="0%"
        Android:duration="700" />
</set>

enter_from_right.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shareInterpolator="false">
    <translate
        Android:fromXDelta="100%" Android:toXDelta="0%"
        Android:fromYDelta="0%" Android:toYDelta="0%"
        Android:duration="700" />
</set>

exit_to_left.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shareInterpolator="false">
    <translate
        Android:fromXDelta="0%" Android:toXDelta="-100%"
        Android:fromYDelta="0%" Android:toYDelta="0%"
        Android:duration="700"/>
</set>

Sortie:

enter image description here

C'est fait .

162
Hiren Patel

Si vous pouvez vous permettre de vous lier à Lollipop et plus tard, cela semble faire l'affaire:

import Android.transition.Slide;
import Android.util.Log;
import Android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.RIGHT));
f.setExitTransition(new Slide(Gravity.LEFT));
getFragmentManager()
    .beginTransaction()
    .replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
    .commit();

J'espère que cela t'aides.

50
scorpiodawg

La réponse de Nurik est très utile, mais je ne parviens pas à la faire fonctionner avant d’avoir trouvé ceci . En bref, si vous utilisez la bibliothèque de compatibilité (par exemple, SupportFragmentManager au lieu de FragmentManager), la syntaxe des fichiers d'animation XML sera différente.

47
strangeluck

Voici une animation slide in/out entre les fragments:

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();

Nous utilisons un objetAnimator.

Voici les deux fichiers XML du sous-dossier animator.

enter_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
     <objectAnimator
         xmlns:Android="http://schemas.Android.com/apk/res/Android"
         Android:duration="1000"
         Android:propertyName="x"
         Android:valueFrom="2000"
         Android:valueTo="0"
         Android:valueType="floatType" />
</set>

exit_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:duration="1000"
        Android:propertyName="x"
        Android:valueFrom="0"
        Android:valueTo="-2000"
        Android:valueType="floatType" />
</set>

J'espère que cela aiderait quelqu'un.

26
kirilv

Pour tous ceux qui se font prendre, assurez-vous que setCustomAnimations est appelée avant l'appel à remplacer/ajouter lors de la création de la transaction.

21
Charlie

L'implémentation de FragmentTransaction dans le SDK Android demande une Animator alors que la bibliothèque de support veut une Animation, ne me demandez pas pourquoi, mais après le commentaire de strangeluk, je me suis penché sur Android 4.0.3. . Android Le SDK utilise loadAnimator() et la bibliothèque de support utilise loadAnimation()

12
sherpya

Essayez d'utiliser cette solution simple et à jeun. Android fournit des valeurs par défaut animations.

fragmentTransaction.setCustomAnimations(Android.R.anim.slide_in_left, Android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(Android.R.anim.slide_in_left, Android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

Sortie:

enter image description here

5
Gowthaman M