Search code examples
androidanimationobjectanimator

Unable to cancel() animation (object is null)


I am attempting to animate (rotate) an ImageView indefinitely on a Button onClick event, then stop it on another Button onClick. Here is my code...

public class MainActivity extends Activity{

ObjectAnimator animation;

public void onCreate(Bundle icicle) {
...

Button start = (Button) findViewById(R.id.startbutton);
start.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        ImageView iv = (ImageView) findViewById(R.id.wheel);
        ObjectAnimator animation = ObjectAnimator.ofFloat(iv, "rotation", 360);
        animation.setInterpolator(null);
        animation.setRepeatCount(animation.INFINITE);
        animation.setDuration(1000);
        animation.start();

        Log.i(TAG, String.valueOf(animation)); // returns the animation object

    }
});

Button stop = (Button) findViewById(R.id.stopbutton);
stop.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {

        Log.i(TAG, String.valueOf(animation)); // returns null

        animation.cancel();
    }
});

The animation starts and runs fine. The app crashes however when the stop button is clicked as the 'animation' object appears to be null.


Solution

  • It's a scope issue -- you have a method local variable and global variable with the same name. You need to take out the other declaration:

    EX:

    public class MainActivity extends Activity{
    
    ObjectAnimator animation;
    
    public void onCreate(Bundle icicle) {
    ...
    
    Button start = (Button) findViewById(R.id.startbutton);
    start.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            ImageView iv = (ImageView) findViewById(R.id.wheel);
    
            //remove declaration here so it uses the globally scoped variable
            animation = ObjectAnimator.ofFloat(iv, "rotation", 360);
            animation.setInterpolator(null);
            animation.setRepeatCount(animation.INFINITE);
            animation.setDuration(1000);
            animation.start();
    
            Log.i(TAG, String.valueOf(animation)); // returns the animation object
    
        }
    });
    
    Button stop = (Button) findViewById(R.id.stopbutton);
    stop.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
    
            Log.i(TAG, String.valueOf(animation)); // returns null
            if(animation != null) //you'll probably wana do a null check
                animation.cancel();
        }
    });