Android animation stop works in recyclerview when view go off the screen

I set animaion like this:

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {     
            Animation anim = AnimationUtils.loadAnimation(context, R.anim.rotate);
            holder.windPropellers.setAnimation(anim);
            break;
}

When the view scrolled off the screen animation stops. And when you scroll back it's not animating at all.

Upvotes: 8

Views: 3263

Answers (3)

Jefferson Trigueiro
Jefferson Trigueiro

Reputation: 461

In my case I needed to show and hide my progress bar that is inside my view holder and sometimes the progress bar was not showing. I followed @jonathanrz and used setHasTransientState(true) answer and it worked, but it made my RecyclerView very lagy and slow. So I end up with the following solution:

progressBar.post {
            // Change visibility here
            progressBar.visibility = GONE
        }

Upvotes: 0

Pierre
Pierre

Reputation: 9052

I used a ProgressBar with a custom image/drawable instead because I couldn't get other answers to work flawlessly.

Set setVisibility(View.GONE/VISIBLE) in onBindViewHolder as needed.

<ProgressBar
    android:id="@+id/pbUpload"
    android:layout_width="52dp"
    android:layout_height="52dp"
    android:layout_gravity="center"
    android:indeterminate="true"
    android:indeterminateDrawable="@drawable/loader_rotate"
    android:indeterminateDuration="1000"
    android:visibility="gone" />

and the Drawable loader_rotate.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
            android:fromDegrees="0"
            android:toDegrees="360"
            android:pivotX="50%"
            android:pivotY="50%"
            android:drawable="@drawable/loader"> <!-- a png image in drawable folders -->
        </rotate>
    </item>
</layer-list>

Upvotes: 2

jonathanrz
jonathanrz

Reputation: 4296

You need to set transient state in the view to prevent it from being recycled.

Your code would look like this:

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {     
        Animation anim = AnimationUtils.loadAnimation(context, R.anim.rotate);
        holder.windPropellers.setHasTransientState(true);
        anim.setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                holder.windPropellers.setHasTransientState(false);
            }
        });
        holder.windPropellers.setAnimation(anim);
        break;

}

Upvotes: 15

Related Questions