Vishnu M. Vishnu M. - 3 months ago 140
Android Question

How to animate RecyclerView items when adapter is initialized (in order)?

What I'm trying to accomplish

I want to make items in a linear vertical RecyclerView appear in order. I want the 1st item to appear, then the 2nd, then the 3rd and so on. Here is an example of the type of animation I'm trying to accomplish.

animation example




What I've tried

I have tried the methods provided in this question: How to animate RecyclerView items when they appear

However, this is not quite what I'm trying to accomplish. This causes all the items in the RecyclerView to appear at once, rather than one at a time.




My code

public class ParentCommentsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private int lastPosition = -1;

//constructor and other code not shown...

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case OP:
OPViewHolder ovh = (OPViewHolder) viewHolder;
configureOPViewHolder(ovh, position);
setAnimation(ovh.getContainer(), position);
break;
case COMMENT:
CommentViewHolder cvh = (CommentViewHolder) viewHolder;
configureCommentViewHolder(cvh, position);
setAnimation(cvh.getContainer(), position);
break;
default:
RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
configureDefaultViewHolder(vh, position);
break;
}

}

@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder viewHolder)
{

switch (viewHolder.getItemViewType()) {
case OP:
((OPViewHolder)viewHolder).clearAnimation();
break;
case COMMENT:
((CommentViewHolder)viewHolder).clearAnimation();
break;
default:
break;
}
}

private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) {
//code...
}

private void configureOPViewHolder(OPViewHolder vh1, int position) {
//code...
}

private void configureCommentViewHolder(CommentViewHolder vh2, int position) {
//code...
}

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, R.anim.fade_in);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}

}

Answer

After you call setAdapter you can run following:

recyclerView.getViewTreeObserver().addOnPreDrawListener(
        new ViewTreeObserver.OnPreDrawListener() {

            @Override
            public boolean onPreDraw() {
                recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);

                for (int i = 0; i < recyclerView.getChildCount(); i++) {
                    View v = recyclerView.getChildAt(i);
                    v.setAlpha(0.0f);
                    v.animate().alpha(1.0f)
                            .setDuration(300)
                            .setStartDelay(i * 50)
                            .start();
                }

                return true;
            }
        });

Example shows simple alpha animation, but you can run what you want in the loop and adjust interpolator, duration and start delay.