web-dev-qa-db-fra.com

Android Fragments et animations

Comment mettre en œuvre le type de glissement utilisé par exemple par le client Honeycomb Gmail?

Est-ce que TransactionManager peut gérer cela automatiquement en ajoutant et en supprimant les Fragments, il est un peu difficile de le tester car l'émulateur est un diaporama :)

259
alexanderblom

Pour animer la transition entre fragments ou pour afficher ou masquer un fragment, utilisez le Fragment Manager afin de créer un Fragment Transaction.

Dans chaque transaction de fragment, vous pouvez spécifier les animations d'entrée et de sortie qui seront utilisées pour afficher et masquer respectivement (ou les deux lorsque l'option de remplacement est utilisée).

Le code suivant montre comment remplacer un fragment en glissant un fragment et en faisant glisser l'autre à sa place.

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();

Pour obtenir le même résultat en masquant ou en affichant un fragment, appelez simplement ft.show ou ft.hide, en transmettant le fragment que vous souhaitez afficher ou masquer, respectivement.

Pour référence, les définitions d'animation XML utiliseraient la balise objectAnimator. Un exemple de slide_in_left pourrait ressembler à ceci:

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

Si vous n'avez pas à utiliser la bibliothèque de support, jetez un coup d'œil à Roman's answer.

Mais si vous souhaitez utiliser la bibliothèque de support , vous devez utiliser l'ancien framework d'animation comme décrit ci-dessous.

Après avoir consulté Reto et blindstuff , j'ai obtenu que le code suivant fonctionne.

Les fragments apparaissent en glissant depuis la droite et en glissant vers la gauche quand on appuie sur le dos.

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

L'ordre est important. Cela signifie que vous devez appeler setCustomAnimations() avant replace() ou l'animation ne prendra pas effet!

Ensuite, ces fichiers doivent être placés dans le dossier res/anim .

enter.xml :

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

exit.xml :

<set>
    <translate xmlns:Android="http://schemas.Android.com/apk/res/Android"
               Android:fromXDelta="0"
               Android:toXDelta="-100%"
               Android:interpolator="@Android:anim/accelerate_interpolator"
               Android:duration="@Android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml :

<set>
    <translate xmlns:Android="http://schemas.Android.com/apk/res/Android"
               Android:fromXDelta="-100%"
               Android:toXDelta="0"
               Android:interpolator="@Android:anim/decelerate_interpolator"
               Android:duration="@Android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml :

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

La durée des animations peut être modifiée pour n’importe laquelle des valeurs par défaut telles que @Android:integer/config_shortAnimTime ou n’importe quel autre nombre.

Notez que si entre les remplacements de fragments une modification de configuration se produit (par exemple une rotation), l'action de retour n'est pas animée. Ceci est un bug documenté qui existe toujours dans la version 20 de la bibliothèque de support.

234
dmanargias

Je vous suggère fortement d'utiliser ceci au lieu de créer le fichier d'animation car c'est une bien meilleure solution. Android Studio fournit déjà la valeur par défaut animation que vous pouvez utiliser sans créer de nouveau fichier XML. Les noms des animations sont Android.R.anim.slide_in_left et Android.R.anim.slide_out_right et vous pouvez les utiliser comme suit:

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

19
Gowthaman M

Ma version modifiée bibliothèque de support prend en charge l’utilisation des animations View (c.-à-d. <translate>, <rotate>) et des animateurs d’objet (c.-à-d. <objectAnimator>) pour les transitions de fragments. Il est implémenté avec NineOldAndroids . Reportez-vous à ma documentation sur github pour plus de détails.

5
mark.kedzierski

Quant à moi, j'ai besoin de la vue direction:

dans -> glisser de droite

out -> glisser à gauche

Ici fonctionne pour moi le code:

slide_in_right.xml

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

slide_out_left.xml

 <set xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <translate Android:fromXDelta="0" Android:toXDelta="-50%p"
                Android:duration="@Android:integer/config_mediumAnimTime"/>
        <alpha Android:fromAlpha="1.0" Android:toAlpha="0.0"
                Android:duration="@Android:integer/config_mediumAnimTime" />
    </set>

code de transaction:

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}
1
Serg Burlaka

Je résous cela de la manière suivante

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
1
Shakawat Hossain