Been doing some animation inside of a row in RecyclerView (not the row itself. Imagine expanding text) and there are times when the animation leaks to other recycled views which should not have that animation in them.
Since I use property animation the scale action resizes the inner view and the leak can be seen in 2 aspects: 1) The animation will go on (This I could overcome with some guards) 2) The view has been resized and stopped in its tracks and so it will be reflected in the recycled view.
How can I reset the views to their original state? I have tried many approaches from posts but none solved it. The closest definition I got was in this unanswered post: How to reset view to original state after using animators to animates its some properties?
Here is a sample of how I set up my animation in onBind (this one has an attempt to use onAnimationEnd which I found in one post but did not work)
ObjectAnimator scaleXUp = ObjectAnimator.ofFloat(mView, View.SCALE_X, 10f);
scaleXUp.setRepeatCount(ValueAnimator.INFINITE);
scaleXUp.setRepeatMode(ValueAnimator.REVERSE);
scaleXUp.setDuration(700);
ObjectAnimator scaleYUp = ObjectAnimator.ofFloat(mView, View.SCALE_Y, 10f);
scaleYUp.setRepeatCount(ValueAnimator.INFINITE);
scaleYUp.setRepeatMode(ValueAnimator.REVERSE);
scaleYUp.setDuration(700);
mTotalAnimation = new AnimatorSet();
mTotalAnimation.play(scaleXUp).with(scaleYUp);
mTotalAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
mTotalAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animation.removeListener(this);
animation.setDuration(0);
for(Animator va : ((AnimatorSet)animation).getChildAnimations()) {
((ValueAnimator)va).reverse();
}
}
});
mTotalAnimation.start();
And here is what I do in the onUnbindData:
if (mTotalAnimation != null) {
mTotalAnimation.end();
mTotalAnimation = null;
}
And as I saw many people like the clearAnimation approach - tried and did not work either.
end()
is necessary. It appears to undo the effect ofreverse()
. Also, to reset values to original state immediately, you will needanim.setDuration(0)
before callinganim.reverse()
Also I noticed that callingmTotalAnimation.setDuration(0)
had no effect, it had to be called on each child animation. – Transmittance