android – CardView within RecyclerView: animation while populating-ThrowExceptions

Exception or error:

I have a recycled view which is populated with CardView layouts. I’ve noticed that in many apps, these items have a nice animated entrance rather than abruptly appearing as they currently do in my application. An example of what I’m trying to achieve is shown below:
enter image description here

How would I use my swipeRefreshListener/adapter to trigger this animation? How would I implement this through my adapter?

Note: I need this animation to also be triggered when the RecyclerView is first populated with the CardView items, and the data they contain.

My RecyclerView’s adapter is shown below:

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

private String[] mDataset;
private String[] mClassDataset;
private int lastPosition = -1;
private Context context;

View view;


public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView mTextView;
    public TextView mClassDataView;
    CardView container;


    public ViewHolder(View itemView) {
        super(itemView);
        mTextView = (TextView)itemView.findViewById(R.id.grade);
        mClassDataView = (TextView)itemView.findViewById(R.id.class_name);
        container = (CardView)itemView.findViewById(R.id.card_view);
    }
}

public RecyclerAdapter(String[] myDataset, String[] classData, Context context) {
    mDataset = myDataset;
    mClassDataset = classData;
    this.context = context;

}

@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_item, parent, false);

    ViewHolder vh = new ViewHolder(v);

    view = v;

    return vh;
}

@Override
public int getItemCount() {
    return mClassDataset.length;
}

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


    if (mDataset.length < mClassDataset.length) {

        holder.mTextView.setText("N/A");
        holder.mClassDataView.setText(mClassDataset[position]);

        if (mClassDataset[position].equals("N/A")) {

        }

    } else {
        holder.mTextView.setText(mDataset[position]);
        holder.mClassDataView.setText(mClassDataset[position]);
    }

    for (int i = 0; i < getItemCount(); i++) {

        animate(view, i);

    }
}

private void animate(final View view, final int position){

        Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
        view.startAnimation(animation);
        lastPosition = position;

    }

}

The animation is currently working, however the thing is the items are being animated all at once. I tried iterating through the items by creating a custom getChild() method, but that didn’t work. Somehow I need to access/animate each child individually and possibly set a delay between each animation. However, I’m not sure how exactly I can accomplish this. I know I can use a Handler to set delay, but accessing each child is a problem.

How to solve:

Use this custom class of RecyclerView, it behaves like the app that you posted its screenshot (Reddit Relay), it prevents scrolling while animating first items.
You may want to custom the animation as you want.

package net.leolink.android.testrecyclerviewentranceanimation;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * @author Leo on 2015/09/03
 */
public class MyRecyclerView extends RecyclerView {
    private boolean mScrollable;

    public MyRecyclerView(Context context) {
        this(context, null);
    }

    public MyRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mScrollable = false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return !mScrollable || super.dispatchTouchEvent(ev);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        for (int i = 0; i < getChildCount(); i++) {
            animate(getChildAt(i), i);

            if (i == getChildCount() - 1) {
                getHandler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mScrollable = true;
                    }
                }, i * 100);
            }
        }
    }

    private void animate(View view, final int pos) {
        view.animate().cancel();
        view.setTranslationY(100);
        view.setAlpha(0);
        view.animate().alpha(1.0f).translationY(0).setDuration(300).setStartDelay(pos * 100);
    }
}

DEMO

Demo

###

First define the animation:

<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
    android:duration="300"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
    android:duration="300" />
</set>

Then set it in your adapter:

    @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.container, 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.push_left_in);
        viewToAnimate.startAnimation(animation);
        lastPosition = position;
    }
}

Referenced from: RecyclerView : How to create insert animation effect?

###

For the RecyclerView you can use ItemAnimators by setting them with this method:

RecyclerView.setItemAnimator(RecyclerView.ItemAnimator animator)

There are a few libraries out there that implement this ItemAnimator, for example this one: https://github.com/wasabeef/recyclerview-animators

Leave a Reply

Your email address will not be published. Required fields are marked *