Reputation: 1067
I have a RecyclerViewAdapter and I would need the items to get animated when they first appear on the screen (i.e. when scrolled down) but only once, for the first time they appear, after that whenever the user scrolls up there shouldn't be any animations.
My code now works perfectly except for that last item, it always gets animated over and over again when I scroll down to it.
private Integer lastPosition = -1;
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.setIsRecyclable(false);
// Animations
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
holder.mImage.setAnimation(AnimationUtils.loadAnimation(context, R.anim.first_animation));
holder.mView.setAnimation(AnimationUtils.loadAnimation(context, R.anim.second_animation));
lastPosition = position -1;
}
}
And if I set lastPosition = position;
I only get the first few items loaded (and visible depending on screen size) animated and when I scroll down they don't get animated whatsoever.
Why is this behavior? As all examples found here for animating items with scrolling for the first time using them
lastPosition = position;
But mine fails?
My RecyclerAdapter is filterable (implements Filterable
) if this would be of any essence to the issue.
Upvotes: 2
Views: 1617
Reputation: 803
This is a workaround you can use in your RecyclerViewAdapter class
ArrayList<Boolean> hasAnimation;
public RecyclerViewAdapter(Context context) {
hasAnimation=new ArrayList<>();
this.context=context;
}
Then in onBindViewHolder method
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
hasAnimation.add(true);
if (hasAnimation.get(position)){
Animation animation1= AnimationUtils.loadAnimation(context, R.anim.first_animation);
Animation animation2= AnimationUtils.loadAnimation(context, R.anim.second_animation);
animation1.setDuration(1000);
animation2.setDuration(1000);
holder.mImage.startAnimation(animation1);
holder.mView.startAnimation(animation2);
hasAnimation.set(position,false);
}}
And For sure you can simplify the process with your code in animation part
holder.mImage.setAnimation(AnimationUtils.loadAnimation(context, R.anim.first_animation));
holder.mView.setAnimation(AnimationUtils.loadAnimation(context, R.anim.second_animation));
Hope that helps
Upvotes: 0
Reputation: 974
You could add additional property to the list item and check when animate and when don't:
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
//Checking if has already animated
if (!list.get(position).hasAnimated()) {
//Mark this ViewHolder as animated
list.get(position).setHasAnimated();
holder.mImage.setAnimation(AnimationUtils.loadAnimation(context, R.anim.first_animation));
holder.mView.setAnimation(AnimationUtils.loadAnimation(context, R.anim.second_animation));
}
}
Upvotes: 1