ObjectAnimator with Infinite rotation stutters
Asked Answered
W

1

11

I have an animator, infinite_rotation, defined as:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="rotation"
        android:repeatCount="infinite"
        android:valueFrom="0"
        android:valueTo="360"
        android:duration="2000" />
</set>

When the time (time is indefinite) comes that I no longer need this, I call infinite_animator.cancel(). Then play a fade_out animation on its layout container:

<set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:propertyName="alpha"
            android:repeatCount="0"
            android:valueTo="0.0"
            android:duration="1000" />
</set>

The resulting animation is that, the rotation stops as expected but stutters while fading out. What am I missing?

Here is how it looks:

enter image description here

UPDATE: I was testing the above problem on old Samsung Tab 4 with Kitkat OS. I just tested on a fairly newer Samsung Tab 4 with Marshmallow OS. The animation works fine. So I guess the better question is how do I fix the sloppy animation on my older device/OS?

This is the animation call:

private void animateRefreshButton() {
    ImageView iv_refresh = (ImageView) findViewById(R.id.iv_refresh);

    if(infinite_animator == null) {
        infinite_animator = AnimatorInflater.loadAnimator(this, R.animator.refresh_rotate);
    }
    infinite_animator.setTarget(iv_refresh);
    infinite_animator.start();
}

hideRefreshButton() is initiated when the app determines refresh is complete. This is the call to cancel and fade out animation:

private void hideRefreshButton() {
    if(infinite_animator != null) {
        infinite_animator.cancel();
    }

    Animator anim = AnimatorInflater.loadAnimator(this, R.animator.refresh_fadeout);
    anim.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {}

        @Override
        public void onAnimationEnd(Animator animation) {
            framelayout_container_of_iv_refresh.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationCancel(Animator animation) {}

        @Override
        public void onAnimationRepeat(Animator animation) {}
    });
    anim.setTarget(framelayout_container_of_iv_refresh);
    anim.start();
}
Woodford answered 14/9, 2017 at 10:41 Comment(8)
Did you try to set fillAfter to true for your rotation animation?Submersed
no. i can try that out. thanks.Woodford
Can you post a gif of that behavior?Loss
yes sure. i will post the gif today.Woodford
@Submersed i think setFillAfter is for View Animation only (?). I am using Property Animation.Woodford
@Loss updated the question with gif in itWoodford
pls add the code where you start and stop the respective animations.Resurge
@Resurge i added the requested codeWoodford
L
21

Personally I do not use Animation API because of the "problems" it has. Instead, I would go with Animators API in this case.

Have this snippet:


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View view = findViewById(R.id.imageView);

        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.ROTATION, 0.0f, 360.0f);

        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(Animation.INFINITE);
        objectAnimator.setInterpolator(new LinearInterpolator());

        objectAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {
                view.animate()
                        .alpha(0.0f)
                        .setDuration(1000);
            }
        });

        objectAnimator.start();

        view.setOnClickListener((v) -> objectAnimator.cancel());

    }

Then this will be the output:

enter image description here


I've tested on emulator (API 19): works as expected.

Loss answered 18/9, 2017 at 8:50 Comment(8)
I am using ObjectAnimator as well. In my case, I created the animator thru an xml resource.Woodford
@user1506104, now I see, sorry for confusion.Loss
@user1506104, can you show how are you starting and canceling your animation, so that we understand why your code works that way?Loss
no worries (+1 still for sharing your idea) ... before i share the code, please see the updated question.Woodford
@user1506104, emulator with API 19 runs the animations as expected. Can you confirm that the code I have shared also stutters?Loss
yes this works. but I should apply the fadeout effect on its container, a RelativeLayoutWoodford
Is that a problem? Instead of view.animate().alpha(0.0f).setDuration(1000) perform relativeLayout.animate().alpha(0.0f).setDuration(1000)Loss
yeah i think thats the problem. I tried to remove the layout, the fade out works fine on the image view.Woodford

© 2022 - 2024 — McMap. All rights reserved.