Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

android

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

}
like image 890
Vishnu M. Avatar asked Aug 12 '16 03:08

Vishnu M.


People also ask

How to animate recyclerview items when they appear on the screen?

This example demonstrates how to animate RecyclerView items when they appear on the screen . Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main.xml. Step 3 − Add the following code to res/anim/down_to_up.xml.

When do the animations play when the item view enters?

The animations would play when the item view entered or exited the zone in the top, or the bottom of the view. In this article I will outline how I implemented this effect and how you can also do this in your application using your code, or the simple library I wrote to achieve this effect.

What is the difference between recycler view and card view?

Recycler view is a more advanced version of the list view and it works based on View holder design pattern. Using recycler view we can show grids and list of items. card view is extended by frame layout and it is used to show items in card manner.


2 Answers

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.

like image 188
Niko Avatar answered Oct 11 '22 12:10

Niko


I have decided to use a different approach from what Niko suggested earlier. His method works great and is very easy, but it was causing some buggy animations when adding and removing items (as can be seen here).

So I decided to try a different approach and use a layout animation controller. Here's the code I used to achieve the same result.

public void initialRVAnimation() {

    AnimationSet set = new AnimationSet(true);

    // Fade in animation
    Animation fadeIn = new AlphaAnimation(0.0f, 1.0f);
    fadeIn.setDuration(400);
    fadeIn.setFillAfter(true);
    set.addAnimation(fadeIn);

    // Slide up animation from bottom of screen
    Animation slideUp = new TranslateAnimation(0, 0, Utils.getScreenHeight(this), 0);
    slideUp.setInterpolator(new DecelerateInterpolator(4.f));
    slideUp.setDuration(400);
    set.addAnimation(slideUp);

    // Set up the animation controller              (second parameter is the delay)
    LayoutAnimationController controller = new LayoutAnimationController(set, 0.2f);
    rv.setLayoutAnimation(controller);

    // Set the adapter
    adapter = new ItemAdapter(data, this);
    recyclerView.setAdapter(adapter);
}
like image 37
Vishnu M. Avatar answered Oct 11 '22 12:10

Vishnu M.