2

I am using RecyclerView and have some animation where I scaleup one of RelativeLayout in ViewHolder item.

Note: It is not the add/remove/insert animation. It starts when user interacts in ViewHolder item. Hence I am not using ItemAnimator here.

Animation works fine but it reappears (final state) in some random View item. I know it is due to reuse of items and I am clearing animation too but it didn't help.

@Override public void onBindViewHolder(ViewHolder viewHolder, int position) { Model model = getModelObject(position); ((Model) viewHolder.itemView).showItem(position); } 

I am doing this in showItem

 relativeLayout.clearAnimation(); relativeLayout.setAnimation(null); 

In onViewDetachedFromWindow

@Override public void onViewDetachedFromWindow(ViewHolder holder) { ((ItemView) holder.itemView).clearAllAnimations(); super.onViewDetachedFromWindow(holder); } 

ClearAllAnimations

 public void clearAllAnimations() { for (RelativeLayout layout : layoutArray) { optionLayout.clearAnimation(); optionLayout.setAnimation(null); } 

Here how I am animating the view

public AnimatorSet onDragStartAnimation(RelativeLayout group[]) { AnimatorSet big = new AnimatorSet(); for (RelativeLayout relativeLayout : group) { ObjectAnimator scaleXSmall = ObjectAnimator.ofFloat(relativeLayout, "scaleX", 1.0f, 0.85f); ObjectAnimator scaleYSmall = ObjectAnimator.ofFloat(relativeLayout, "scaleY", 1.0f, 0.85f); big.playTogether(scaleXSmall, scaleYSmall); } return big; } 

it is not working. RelativeLayout not resetting and appearing in scaledup state in some random View Item.

Update

I did small experiment: Set alpha animation on ImageView in ViewHolder item like this

Animation fadeInAnimation = AnimationUtils.loadAnimation(mContext, R.anim.fadein); imageView.startAnimation(fadeInAnimation); 

and used clear animation. imageView.clearAnimation(); it worked and ImageView was visible normal when next time ViewItem appears on the screen.

But same is not working if I do this

alphaAnimator = ObjectAnimator.ofFloat(centerImageView, "alpha", 1.0f, 0.5f); alphaAnimator.start(); 

And to clear this

 alphaAnimator.removeAllListeners(); alphaAnimator.cancel(); alphaAnimator.end(); 

this didn't work. Alpha animation remains in ViewHolder image item.

7
  • Where you're calling this code? Commented Jan 17, 2016 at 9:46
  • Try to clear the animation in onChildDetachedFromWindow() Commented Jan 17, 2016 at 10:06
  • do I need to extend RecyclerView to do this? Commented Jan 17, 2016 at 10:15
  • Sorry i mean onViewDetachedFromWindow(), you can override it from the adapter Commented Jan 17, 2016 at 10:23
  • Didn't help... see updates Commented Jan 17, 2016 at 10:32

3 Answers 3

2

I solved the problem in this way. Everything works fine.

GroupsViewHolder - it is custom RecyclerView.ViewHolder

@Override public void onViewAttachedToWindow(GroupsViewHolder holder) { super.onViewAttachedToWindow(holder); //here add animation } @Override public void onViewDetachedFromWindow(GroupsViewHolder holder) { //here clear animation super.onViewDetachedFromWindow(holder); } 
Sign up to request clarification or add additional context in comments.

Comments

1

By inspiring from crymson's answer from Crymson's answer I have made little easy and useful solution using tag method of View instead setting a boolean in complicated logic of your custom adapter.

@Override public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { super.onViewDetachedFromWindow(holder); if (holder.getItemViewType() == TYPE_AD) ((ViewHolderForAd) holder).ivStory.setTag(false); } public class ViewHolderForAd extends RecyclerView.ViewHolder { private ImageView ivStory; TextView tvName; public ViewHolderForAd(View view) { super(view); ivStory = (ImageView) view.findViewById(R.id.ivStoryImage); tvName = (TextView) view.findViewById(R.id.tvAppName); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int pos = getAdapterPosition(); if (pos < 0) { pos = (int) v.getTag(); } customItemClickListener.onItemClicked(v, pos); } }); //ivStory.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulse_story)); ivStory.setTag(false); //Set default tag false to decrease risk of null } } @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) { //...Your code... if (!(boolean) holder1.ivStory.getTag()) { holder1.ivStory.setTag(true); holder1.ivStory.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulse_story)); } //...Your code...// } 

You can use setTag(key, object) instead of setTag(object) if you already tagged something(like position) in your imageView. Hope this helps someone.

Comments

0

I solved it by doing reverse animation of all animators in onViewDetachedFromWindow.

@Override public void onViewDetachedFromWindow(ViewHolder holder) { if (holder.getItemViewType() == 1) ((MyItemView) holder.itemView).reverseAllAnimations(); } 

2 Comments

What is reverseAllAnimations();? I can't find such method.
No method reverseAllAnimations() in view.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.