1

J'essaie de créer une simple diapositive d'animation pour une vue recycleur existante. Supposons que le recycleur possède 50 objets, que le jeu de données ait changé et qu'il ne contienne plus que 40 objets, que les éléments aient été remplacés, que tous les 50 éléments précédents ne soient plus pertinents.Recycler View Animation, l'ancien ViewHolder reste visible

Ainsi, notifyDatasetChanged() est appelée après la structure de données a été modifiée et les nouveaux éléments sont animés dans.

Le problème est que vous pouvez encore voir les 40 précédents articles ci-dessous les nouveaux éléments, sur le même l'espace de chaque cellule, vous voyez à la fois les données précédentes et les nouvelles données. Le code de la sous-classe ItemAnimator est ci-dessous, si j'ajoute une animation de suppression qui change l'opacité de la cellule de suppression, elle sera invisible mais les éléments de décoration (lignes de liste) sont supprimés, je préfèrerais supprimer entièrement les éléments et ne le rends pas invisible.

public class RVSlideAnimation extends RecyclerView.ItemAnimator { 

    List<RecyclerView.ViewHolder> mViewHolders = new ArrayList<RecyclerView.ViewHolder>(); 

    @Override 
    public void runPendingAnimations() { 
     if (!mViewHolders.isEmpty()) { 
      int animationDuration = 250; 
      AnimatorSet animator; 
      View target; 
      for (final RecyclerView.ViewHolder viewHolder : mViewHolders) { 
       target = viewHolder.itemView; 
       target.setPivotX(target.getMeasuredWidth()/2); 
       target.setPivotY(target.getMeasuredHeight()/2); 

       animator = new AnimatorSet(); 

       animator.playTogether(
         ObjectAnimator.ofFloat(target, "translationX", target.getMeasuredWidth(), 0.0f), 
         ObjectAnimator.ofFloat(target, "alpha", target.getAlpha(), 1.0f) 
       ); 

       animator.setTarget(target); 
       animator.setDuration(animationDuration); 
       animator.setInterpolator(new AccelerateDecelerateInterpolator()); 
       animator.setStartDelay((animationDuration * viewHolder.getAdapterPosition())/10); 
       animator.addListener(new Animator.AnimatorListener() { 
        @Override 
        public void onAnimationStart(Animator animation) { 

        } 

        @Override 
        public void onAnimationEnd(Animator animation) { 
         mViewHolders.remove(viewHolder); 
        } 

        @Override 
        public void onAnimationCancel(Animator animation) { 

        } 

        @Override 
        public void onAnimationRepeat(Animator animation) { 

        } 
       }); 
       animator.start(); 
      } 
     } 
    } 

    @Override 
    public boolean animateRemove(RecyclerView.ViewHolder viewHolder) { 
     //viewHolder.itemView.animate().alpha(0).setDuration(100); 
     return false; 
    } 

    @Override 
    public boolean animateAdd(RecyclerView.ViewHolder viewHolder) { 
     viewHolder.itemView.setAlpha(0.0f); 
     return mViewHolders.add(viewHolder); 
    } 

    @Override 
    public boolean animateMove(RecyclerView.ViewHolder viewHolder, int i, int i2, int i3, int i4) { 
     return false; 
    } 

    @Override 
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) { 
     return false; 
    } 

    @Override 
    public void endAnimation(RecyclerView.ViewHolder viewHolder) { 
    } 

    @Override 
    public void endAnimations() { 
    } 

    @Override 
    public boolean isRunning() { 
     return !mViewHolders.isEmpty(); 
    } 

} 
+0

Êtes-vous sûr de mettre à jour la logique de données? Pouvez-vous ajouter le code pour la mise à jour des données? – HellCat2405

+0

Sans l'ItemAnimator, tout fonctionne correctement, les éléments sont remplacés sans aucun 'chevauchement'. la logique de données de mise à jour n'est pas le problème (je ne peux pas vraiment le télécharger comme un extrait) mais vous pouvez supposer que j'ai une liste d'objets qui sont remplacés par une liste différente, donc toutes les données sont nouvelles. – aviran

Répondre

0

recyclerView.destroyDrawingCache(); avant notifyDatasetChaged() a résolu le problème pour moi.