Jeff Axelrod
Jeff Axelrod

Reputation: 28188

Why is ImageView alpha animation behaving unexpectedly?

I'm trying to fade out an ImageView using an animation. The animation runs, fading out the ImageView, but then the image goes back to fully opaque. Why does this happen?

private void fadeOutImage() {
   final ImageView imageView = (ImageView) activity.findViewById(R.id.imageView);
   imageView.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.fadeout));
}

I tried setting the alpha to zero as below, but then the image never showed up period. Why not?

private void fadeOutImage() {
   final ImageView imageView = (ImageView) activity.findViewById(R.id.imageView);
   imageView.setAlpha(0);
   imageView.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.fadeout));
}

To get this to work, I had to create an AnimationListener, overload the onAnimationEnd, and set the alpha to be zero there. Why?

  final ImageView imageView = (ImageView) activity.findViewById(id);
  Animation animation = AnimationUtils.loadAnimation(activity, R.anim.fadeout);
  animation.setAnimationListener(new AnimationListener() {

     @Override public void onAnimationStart(Animation animation) { 
        imageView.setAlpha(255);
     }

     @Override public void onAnimationRepeat(Animation animation) { }

     @Override public void onAnimationEnd(Animation animation) {
        imageView.setAlpha(0);
     }
  });
  imageView.startAnimation(animation);

Animation XML:

<alpha
    android:duration="1500"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="0.0" />

Upvotes: 1

Views: 3994

Answers (2)

skyrift
skyrift

Reputation: 743

When you start an animation, it literally takes whatever the view currently looks like, animates it according to your supplied animation, but doesn't ever actually change the state of the view.

This can get confusing, but in your first case, after the animation ends, the ImageView just goes back to whatever it looked like before the animation - in your case, the normal opaque.

In your second example, you are setting the alpha to zero before the animation starts, and so when the animation begins playing, the image is already invisible, and so it animates this invisible ImageView - which you can't see.

Therefore, the required sequence is to start the animation before changing the ImageView at all, let it play out, and then the moment the animation ends, change the state of the ImageView so that it disappears before it gets redrawn in it's original state. This is what overriding onAnimationEnd() does.

So, to recap, in the proper implementation, there are two things that affect how the ImageView gets drawn:

  • The animation, which affects how the ImageView looks only while the animation is playing.
  • The imageView.setAlpha(0); method call, to keep the image invisible once the animation finishes.

Note: to possibly increase performance, I'd suggest using

imageView.setVisibility(View.INVISIBLE); 

instead of imageView.setAlpha(0);

Upvotes: 7

Jeff Axelrod
Jeff Axelrod

Reputation: 28188

I'm trying to fade out an ImageView using an animation. The animation runs, fading out the ImageView, but then the image goes back to fully opaque. Why does this happen?

The animation's effects are temporary. Once the animation has completed, the view returns to its state before the animation began.

I tried setting the alpha to zero as below, but then the image never showed up period. Why not?

Though apparently undocumented, the fromAlpha and toAlpha parameters appear to act in a multiplicative fashion. 100% of zero is still zero. I verified this by starting the alpha to a very low value, and I could see that the animation caused the alpha to start at the low value and fade to transparent.

To get this to work, I had to create an AnimationListener, overload the onAnimationEnd, and set the alpha to be zero there. Why?

Since the animation's effects are temporary, you need to set the object to be transparent after the animation. You also have to make sure you reset the object to be opaque before you start the animation.

It looks like you can use an ObjectAnimator starting in API 11 to set the alpha (or any other property's) values directly using rather than multiplicatively.

Upvotes: 1

Related Questions