tccpg288
tccpg288

Reputation: 3352

How To Add RecyclerView Slide In Animation for New Item

I have a RecyclerView and add items to mCommentArrayList at index 0. I am trying to create a slide-in animation at the top of the view as new items (CardViews) are added to the RecyclerView.

I know there are libraries that can be used, and I have even explored https://github.com/wasabeef/recyclerview-animators. However, the documentation is limited and I am unsure what approach to take.

Note that I add all new items to my mCommentArrayList at index 0 so that they appear at the top of the view. I know there is some work to be done in the adapter, specifically onBindViewHolder(), but I don't know exactly what to put in order to activate the animations.

Where I first call to Firebase to find data to populate the RecyclerView:

    mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            setImage(dataSnapshot);
            setQuestion(dataSnapshot);
            createInitialCommentIDArray(dataSnapshot);
            mNumberOfCommentsAtPoll = (int) dataSnapshot.child(COMMENTS_LABEL).getChildrenCount();
            for (int i = 0; i < mNumberOfCommentsAtPoll; i++) {
                String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("COMMENT").getValue();
                Log.v("COMMENT_ID", "The comment ID is " + commentID);
                String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("USER_ID").getValue();
                Log.v("USER_ID", "The user ID is " + userID);
                mCommentArrayList.add(0, new Comments(mUserAvatar, userID, commentID));
                mCommentAdapter.notifyDataSetChanged();
            }

        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });

Subsequent Calls to Firebase on Data Change:

@Override
protected void onStart() {
    super.onStart();
    mUpdateComments = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            mNumberOfCommentsAtPoll = (int) dataSnapshot.getChildrenCount();
            for (DataSnapshot x : dataSnapshot.child(COMMENTS_LABEL).getChildren()) {
                Log.v("DATA_SNAPSHOT", x.toString());
                if (mCommentIDArrayList.contains(x.getKey())) {
                    Log.v("Comment_Already_Added", x.getKey());
                } else {
                    Log.v("Child_Added_Called", "Child Added Called");
                    mCommentIDArrayList.add(x.getKey());
                    String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(x.getKey()).child("COMMENT").getValue();
                    Log.v("New_Comment", "The new comment is " + commentID);
                    String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(x.getKey()).child("USER_ID").getValue();
                    Log.v("New_User_ID", "The new userID is " + userID);
                    mCommentArrayList.add(0, new Comments(mUserAvatar, userID, commentID));
                    mPollCommentsList.getAdapter().notifyItemInserted(0);
                }
            }
        }

Upvotes: 4

Views: 20972

Answers (3)

Saurabh Gaddelpalliwar
Saurabh Gaddelpalliwar

Reputation: 1645

Hope this code help's you !

create one animation file animation_from_right.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="700"
android:fillAfter="false"
>

<translate
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="100%p"
android:toXDelta="0"
/>

<alpha
android:fromAlpha="0.5"
android:toAlpha="1"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
/>

</set>

in Activity

Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.animation_from_right);
        holder.itemView.startAnimation(animation);

use above code in your Adapter on onBindViewHolder

Upvotes: 6

Vaibhav Sharma
Vaibhav Sharma

Reputation: 2319

The best way animate the recyclerview will be to do it in the onbindviewholder method.

Here is how to do it-

create a field variable lastAnimatedPosition in the adapter class.

private int lastAnimatedPosition = -1;

Then in the onbindviewholder-

 @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Comments comment = mDataSet.get(position);
        holder.userComment.setText(comment.getUserComment());
        holder.userID.setText("User " + position);
if (position > lastAnimatedPosition) {
      lastAnimatedPosition = position;
      Animation animation = AnimationUtils.loadAnimation(context, R.anim.my_anim_set);
      animation.setInterpolator(new AccelerateDecelerateInterpolator());
      ((ViewHolder) holder).container.setAnimation(animation);
      animation.start();
    }
    }

Next a few tweaks in your viewholder class-

public class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        protected ImageView userAvatar;
        protected TextView userID;
        protected TextView userComment;
        **protected View container;**


        public ViewHolder(View v) {
            super(v);
            **container = v;**
            userAvatar = (ImageView) v.findViewById(R.id.profile_image);
            userID = (TextView) v.findViewById(R.id.user_ID);
            userComment = (TextView) v.findViewById(R.id.user_comment_textview);
        }

        **public void clearAnimation() {
          container.clearAnimation();
        }**
    }

And lastly simply override onViewDetachedFromWindow-

@Override
  public void onViewDetachedFromWindow(final ViewHolder holder) {
    holder.clearAnimation();
  }

UPDATE

Since the element to be animated is in the 0th index replace the if (position > lastAnimatedPosition) snippet with -

if (position == 0) {
      lastAnimatedPosition = position;
      Animation animation = AnimationUtils.loadAnimation(context, R.anim.my_anim_set);
      animation.setInterpolator(new AccelerateDecelerateInterpolator());
      ((ViewHolder) holder).container.setAnimation(animation);
      animation.start();
    }

Upvotes: 0

Jeffalee
Jeffalee

Reputation: 1085

Using the library you were talking about (https://github.com/wasabeef/recyclerview-animators) it's very easy to add a SlideInAnimator to your RecyclerView. Just use the following code to set an Animator to your RecyclerView (pick one):

    recyclerView.setItemAnimator(new SlideInDownAnimator());
    recyclerView.setItemAnimator(new SlideInRightAnimator());
    recyclerView.setItemAnimator(new SlideInLeftAnimator());
    recyclerView.setItemAnimator(new SlideInUpAnimator());

Once you have done this the you can simply trigger the animation by calling notifyItemInserted(position) or notifyItemRangeInserted(positionStart, itemCount). These calls will trigger the Animator, calling notifyDatasetChanged() won't.

Triggering the insertion animation:

    recyclerView.getAdapter().notifyItemInserted(position);
    recyclerView.getAdapter().notifyItemRangeInserted(positionStart, itemCount);

Upvotes: 9

Related Questions