Arny
Arny

Reputation: 462

Android view animation stops when view out of screen

I'm having a recyclerView with several views and one is the animation view which has an animation applied to it. Once the view is out of the screen the animation is no longer active, even though the animation still exists.

The data:

rotate_around_center_point.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >

    <rotate
        android:duration="2500"
        android:interpolator="@android:anim/linear_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:repeatMode="restart"
        android:toDegrees="360" />

</set>

Applying animation:

                animation = AnimationUtils.loadAnimation(this.getContext(),
                        R.anim.rotate_around_center_point);
                loadingRotatingCircleIV.startAnimation(animation);

I could not find any way to catch an event when the animation is interrupted so I'm able to restart the animation once it was out of the screen.

Upvotes: 9

Views: 2112

Answers (4)

chundk
chundk

Reputation: 1

create **HashMap<Integer, Boolean>** for saving each items animation loaded status

construct (){
for(int c = 0; c < adapterDataList.size(); c++){
//Here is create default status of animation loaded status used Boolean to saving
}
}

//Call Start Animation with onViewAttachedToWindow
@Override
public void onViewAttachedToWindow(ItemViewHolder holder) {
    super.onViewAttachedToWindow(holder);

// get HashMap of each items Animation status like this
if(!HashMap.get(position)){ //FALSE means animation not loaded yet
//Here should call start Animation method;
} else {
//Here call no animation method, like setImageDrawable etc...
}

   //create an AnimationListener for each item, when an animation is End, Listener should call a method to change HashMap above which you just created, like this **HashMap.put(position, Boolean.valueOf(true))** //TRUE means animation loaded
}

//to get position value as Integer use holder.getLayoutPosition()

Upvotes: 0

Alex_297
Alex_297

Reputation: 249

If you want to use a ViewAnimation for a RecyclerView item, you have to restore animation in overriden method of RecyclerView - onViewAttachedToWindow(ItemViewHolder holder), like:

@Override
public void onViewAttachedToWindow(ItemViewHolder holder) {
    super.onViewAttachedToWindow(holder);

    if (holder.animated) 
    {
        Animation anim = new ScaleAnimation(0.8f, 1.2f, 
            0.8f, 1.2f,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setFillAfter(true);
        anim.setInterpolator(new BounceInterpolator());
        anim.setDuration(1100);
        anim.setRepeatCount(Animation.INFINITE);
        anim.setRepeatMode(Animation.REVERSE);
        holder.animatedView.startAnimation(anim);
    }
}

Upvotes: 4

michal.z
michal.z

Reputation: 2075

RecyclerView is incorrectly stopping animation on the view when view goes out from screen only if you apply View Animation to that view. If you will use Property Animation everything works properly. So the following solution will work:

ObjectAnimator animator = ObjectAnimator.ofFloat(loadingRotatingCircleIV, "rotation", 0.0f, 360.0f);
animator.setDuration(1000L);
animator.setRepeatCount(ObjectAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.start(); 

Upvotes: 7

Marko Gajić
Marko Gajić

Reputation: 431

I'm doing the exact same thing right now, and having the exact same problem. So the question is how to restart the animation once the view is back on screen.

I got the problem 99% resolved just by calling "loadingRotatingCircleIV.startAnimation(animation);" inside onBindViewHolder every time it gets called for my animated view's position.

But there's just a tiny little problem left. If you scroll down by just a little, so the view gets off screen, but it's view holder doesn't get recycled, when you scroll back up, onBindViewHolder is obviously not called again, but the animation is stopped.. So I'm still trying to fix that one..

So, my current solution:

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
...
        if (position=="animated_view_position") view.startAnimation(animation);
...
}

If somebody has a better solution, please help.

Upvotes: 0

Related Questions