1

I have a simple activity that shows an animation with ObjectAnimator. The animation is created and started in onCreate method of the activity, it is a very simple animation:

cloudAnim = ObjectAnimator.ofFloat(cloud1ImageView, "x", sw);
        cloudAnim.setDuration(35000);
        cloudAnim.setRepeatCount(ValueAnimator.INFINITE);
        cloudAnim.setRepeatMode(ValueAnimator.RESTART);
        cloudAnim.setInterpolator(null);
        cloudAnim.start();

it simply displays a cloud on the left of the screen and moves from the left to the right.

The problem is that in my nexus 5 (android 4.4 lastet version) the cloud is doing a frame jump when the activity starts.

This jump is only visible in my nexus 5, because i'm testing the app also in a huawei ascend y300 devide with android 4.1 and the jump is not visible, the movement is very smooth.

What is wrong with ObjectAnimator and Android 4.4?

Thanks

NullPointerException
  • 36,107
  • 79
  • 222
  • 382

1 Answers1

0

Starting animations in onCreate is not a good idea. When user will finally be able to see this animation (after activity being inflated and displayed on the screen with animation etc.) the animation is not in it's beginning but a bit after it, so user will miss the very beginning of the animation or perhaps will see some frame drops then as well. The final result really depends on the device, android version, standard window animations styles etc.

If you want to launch an animation right after creating an activity make use of onWindowFocusChanged method: http://developer.android.com/reference/android/app/Activity.html#onWindowFocusChanged(boolean)

Called when the current Window of the activity gains or loses focus. This is the best indicator of whether this activity is visible to the user.


In addition you need to do some checks:

    1. Window has focus (hasFocus==true) - it's visible to the user
    2. Create boolean variable indicating that animation was already started, so it will be launched only once
private boolean cloudAnimStarted;

@Override
public void onWindowFocusChanged (boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   if (hasFocus && !cloudAnimStarted) {
       cloudAnimStarted = true;
       cloudAnim.start();
   }
}

So creating a cloudAnim object is fine in onCreate, but launching it should be done in onWindowFocusChanged method instead.

Maciej Ciemięga
  • 10,125
  • 1
  • 41
  • 48
  • i tryed it and it haves the same failure... exactly the same problem – NullPointerException Jul 13 '14 at 11:34
  • I guess that you've removed the "cloudAnim.start();" from onCreate? Please give this animation some delay, like 5 seconds )to be sure that activi creation doesn't affecting it) - just for a test to see whether the framedrop is related with activity creation or does it happened at any time. BTW. Why are you using "setInterpolator(null);"?? null value should not be valid here anyway... If you want to use default LinearInterpolator just remove this line. – Maciej Ciemięga Jul 13 '14 at 11:44
  • 1
    Just FYI:null is valid (check the value animator class which object animator extends) and the default interpolator is acceleratedecelerate, not linear – Whitney Jul 14 '14 at 16:01
  • @Whitney: Thanks! You are absolutely right about the AccelerateDecelerate being default in Animator. I've mistaken it with Animation class, LinearInterpolator is a default value there. http://developer.android.com/reference/android/view/animation/Animation.html – Maciej Ciemięga Jul 14 '14 at 17:28