2

I'm trying to create a simple slide in animation for an existing recycler view.

Lets say the recycler holds 50 items, at some point the dataset has change and now contains only 40 items, the items have been replaced, all the previous 50 items are not relevant anymore.

So, notifyDatasetChanged() is being called after the data structure has been modified and the new items are animated in.

The problem is you can still see the previous 40 items below the new items, on the same space of each cell, you see both the previous data and the new data.

the code for ItemAnimator subclass is below, if I add a remove animation that changes the opacity of the remove cell it will be invisible but the item decoration (list lines) are not removed, I would prefer to remove the items entirely and not make it 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();
    }

} 
Aviran
  • 5,160
  • 7
  • 44
  • 76
  • Are you sure that you update data logic is correct? Can you add the code for data updating? – HellCat2405 Oct 20 '15 at 12:17
  • Without the ItemAnimator everything works fine, the items are being replaced without any 'overlapping'. the update data logic is not the issue (i can't really upload it as a snippet) but you can assume I have a list of objects which at some point is replaced with a different list, so all the data is new. – Aviran Oct 20 '15 at 12:26

1 Answers1

0

recyclerView.destroyDrawingCache(); before notifyDatasetChaged() solved the issue for me.

Aviran
  • 5,160
  • 7
  • 44
  • 76