Comment animer les éléments RecyclerView lorsqu’ils apparaissent

Comment animer les RecyclerViews lorsqu’il y en a?

L’animateur d’élément par défaut n’anime que lorsqu’une donnée est ajoutée ou supprimée après la définition des données du recycleur. Je suis en train de développer de nouvelles applications et je n’ai aucune idée par où commencer.

Des idées pour y parvenir?

MODIFIER :

Selon la documentation ItemAnimator :

Cette classe définit les animations qui ont lieu sur les éléments lorsque des modifications sont apscopes à l’adaptateur.

Donc, à moins que vous ajoutiez vos éléments un par un à votre RecyclerView et rafraîchissiez la vue à chaque itération, je ne pense pas que ItemAnimator soit la solution à vos besoins.

Voici comment animer les éléments RecyclerView lorsqu’ils apparaissent à l’aide d’un CustomAdapter:

 public class CustomAdapter extends RecyclerView.Adapter { private Context context; // The items to display in your RecyclerView private ArrayList items; // Allows to remember the last item shown on screen private int lastPosition = -1; public static class ViewHolder extends RecyclerView.ViewHolder { TextView text; // You need to resortingeve the container (ie the root ViewGroup from your custom_item_layout) // It's the view that will be animated FrameLayout container; public ViewHolder(View itemView) { super(itemView); container = (FrameLayout) itemView.findViewById(R.id.item_layout_container); text = (TextView) itemView.findViewById(R.id.item_layout_text); } } public CustomAdapter(ArrayList items, Context context) { this.items = items; this.context = context; } @Override public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_item_layout, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.text.setText(items.get(position)); // Here you apply the animation when the view is bound setAnimation(holder.itemView, position); } /** * Here is the key method to apply the animation */ private void setAnimation(View viewToAnimate, int position) { // If the bound view wasn't previously displayed on screen, it's animated if (position > lastPosition) { Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left); viewToAnimate.startAnimation(animation); lastPosition = position; } } } 

Et votre custom_item_layout ressemblerait à ceci:

    

Pour plus d’informations sur CustomAdapters et RecyclerView , reportez-vous à cette formation sur la documentation officielle .

Problèmes sur défilement rapide

L’utilisation de cette méthode pourrait entraîner des problèmes de défilement rapide. La vue peut être réutilisée pendant que l’animation se produit. Afin d’éviter cela, il est recommandé d’effacer l’animation quand est détaché.

  @Override public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder) { ((CustomViewHolder)holder).clearAnimation(); } 

Sur CustomViewHolder:

  public void clearAnimation() { mRootLayout.clearAnimation(); } 

Vieille réponse:

Jetez un coup d’oeil au repo de Gabriele Mariotti , je suis sûr que vous trouverez ce dont vous avez besoin. Il fournit des ItemAnimators simples pour RecyclerView, tels que SlideInItemAnimator ou SlideScaleItemAnimator.

J’ai animé le fondu des éléments Recyclerview lorsqu’ils apparaissent pour la première fois, comme indiqué dans le code ci-dessous. Peut-être que cela sera utile à quelqu’un.

 private final static int FADE_DURATION = 1000; //FADE_DURATION in milliseconds @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.getTextView().setText("some text"); // Set the view to fade in setFadeAnimation(holder.itemView); } private void setFadeAnimation(View view) { AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); anim.setDuration(FADE_DURATION); view.startAnimation(anim); } 

Vous pouvez également remplacer setFadeAnimation() par la commande setScaleAnimation() pour animer l’apparence des éléments en les redimensionnant d’un point:

 private void setScaleAnimation(View view) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(FADE_DURATION); view.startAnimation(anim); } 

Le code ci-dessus contient des verrous dans la mesure où, lorsque vous faites défiler les éléments RecyclerView sont toujours fondus ou mis à l’échelle. Si vous le souhaitez, vous pouvez append du code pour permettre à l’animation de se produire lorsque le fragment ou l’activité contenant RecyclerView est créé (par exemple, obtenir l’heure système lors de la création et autoriser uniquement l’animation pour la première milliseconde FADE_DURATION).

J’ai créé une animation à partir de la réponse de pbm avec peu de modification pour que l’animation ne soit exécutée qu’une seule fois

dans l’autre mot, l’ Animation appear with you scroll down only

 private int lastPosition = -1; private void setAnimation(View viewToAnimate, int position) { // If the bound view wasn't previously displayed on screen, it's animated if (position > lastPosition) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501) viewToAnimate.startAnimation(anim); lastPosition = position; } } 

et dans onBindViewHolder appelez la fonction

 @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.getTextView().setText("some text"); // call Animation function setAnimation(holder.itemView, position); } 

Voici un bon sharepoint départ: https://github.com/wasabeef/recyclerview-animators/blob/master/animators/src/main/java/jp/wasabeef/recyclerview/adapters/AnimationAdapter.java

Vous n’avez même pas besoin de la bibliothèque complète, cette classe est suffisante. Ensuite, si vous implémentez simplement votre classe Adapter en donnant un animateur comme celui-ci:

 @Override protected Animator[] getAnimators(View view) { return new Animator[]{ ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0) }; } @Override public long getItemId(final int position) { return getWrappedAdapter().getItemId(position); } 

vous verrez des éléments apparaître depuis le bas pendant leur défilement, évitant également le problème du défilement rapide.

Vous pouvez append un Android: layoutAnimation = “@ anim / rv_item_animation” atsortingbut à RecyclerView comme ceci:

  

merci pour l’excellent article ici: https://proandroiddev.com/enter-animation-using-recyclerview-and-layoutanimation-part-1-list-75a874a5d213

L’animation d’éléments dans la recyclerview lorsqu’ils sont liés dans l’adaptateur n’est peut-être pas la meilleure idée, car cela peut entraîner une animation des éléments de la liste de recyclage à des vitesses différentes. Dans mon cas, l’élément à la fin de la recyclerview s’anime plus rapidement que ceux du haut car ceux du haut ont encore du mal à se déplacer.

Le code original que j’ai utilisé pour animer chaque article dans la liste de recyclage peut être trouvé ici:

http://frogermcs.github.io/Instagram-with-Material-Design-concept-is-getting-real/

Mais je vais copier et coller le code au cas où le lien se briserait.

ÉTAPE 1: Définissez cette option dans votre méthode onCreate pour vous assurer que l’animation ne s’exécute qu’une seule fois:

 if (savedInstanceState == null) { pendingIntroAnimation = true; } 

ÉTAPE 2: Vous devrez mettre ce code dans la méthode où vous souhaitez lancer l’animation:

 if (pendingIntroAnimation) { pendingIntroAnimation = false; startIntroAnimation(); } 

Dans le lien, l’auteur anime les icons de la barre d’outils, il les met donc dans cette méthode:

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); inboxMenuItem = menu.findItem(R.id.action_inbox); inboxMenuItem.setActionView(R.layout.menu_item_view); if (pendingIntroAnimation) { pendingIntroAnimation = false; startIntroAnimation(); } return true; } 

ÉTAPE 3: Maintenant, écrivez la logique pour startIntroAnimation ():

 private static final int ANIM_DURATION_TOOLBAR = 300; private void startIntroAnimation() { btnCreate.setTranslationY(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size)); int actionbarSize = Utils.dpToPx(56); toolbar.setTranslationY(-actionbarSize); ivLogo.setTranslationY(-actionbarSize); inboxMenuItem.getActionView().setTranslationY(-actionbarSize); toolbar.animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(300); ivLogo.animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(400); inboxMenuItem.getActionView().animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(500) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { startContentAnimation(); } }) .start(); } 

Mon alternative préférée:

Je préfère animer l’ensemble de la recyclerview au lieu des éléments contenus dans la recyclerview.

Les étapes 1 et 2 restnt les mêmes.

Dans STEP 3, dès que votre appel API retourne avec vos données, je lancerais l’animation.

 private void startIntroAnimation() { recyclerview.setTranslationY(latestPostRecyclerview.getHeight()); recyclerview.setAlpha(0f); recyclerview.animate() .translationY(0) .setDuration(400) .alpha(1f) .setInterpolator(new AccelerateDecelerateInterpolator()) .start(); } 

Cela animerait l’intégralité de votre recyclerview pour qu’il vienne du bas de l’écran.

Créez cette méthode dans votre adaptateur recyclerview

 private void setZoomInAnimation(View view) { Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file view.startAnimation(zoomIn); } 

Et enfin, ajoutez cette ligne de code dans onBindViewHolder

setZoomInAnimation(holder.itemView);

Il suffit de prolonger votre adaptateur comme ci-dessous

 public class RankingAdapter extends AnimatedRecyclerView 

Et append la méthode super à onBindViewHolder

 @Override public void onBindViewHolder(ViewHolder holder, final int position) { super.onBindViewHolder(holder, position); 

C’est un moyen automatique de créer un adaptateur animé comme “Basheer AL-MOMANI”

 import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; import java.util.Random; /** * Created by eliaszkubala on 24.02.2017. */ public class AnimatedRecyclerView extends RecyclerView.Adapter { @Override public T onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(T holder, int position) { setAnimation(holder.itemView, position); } @Override public int getItemCount() { return 0; } protected int mLastPosition = -1; protected void setAnimation(View viewToAnimate, int position) { if (position > mLastPosition) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501) viewToAnimate.startAnimation(anim); mLastPosition = position; } } } 

Ajoutez cette ligne à RecyclerView.xml

 android:animateLayoutChanges="true"