I am drawing a scaled bitmap onto a canvas and would like to fade my image out at a specified time.
Basically, when my character image goes over a certain section of the
The best way for me to explain this is provide a full custom view example that you can pull the pieces from that you need. Below is a view that accomplishes this.
public class CharacterView extends View {
private Paint mCharacterPaint;
private Bitmap mCharacterBitmap;
private Transformation mTransformation;
private AlphaAnimation mFadeOut;
public CharacterView(Context context) {
super(context);
init(context);
}
public CharacterView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CharacterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
//This would be your character image instead
mCharacterBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//We need a paint to efficiently modify the alpha
mCharacterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//This is needed to house the current value during the animation
mTransformation = new Transformation();
//Construct an animation that will do all the timing math for you
mFadeOut = new AlphaAnimation(1f, 0f);
mFadeOut.setDuration(500);
//Use a listener to trigger the end action
mFadeOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
//Trigger your action to change screens here.
}
@Override
public void onAnimationRepeat(Animation animation) { }
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//In this example, touching the view triggers the animation
// your code would run this sequence when the character reaches the
// appropriate coordinates (P.S. I would not advocate putting this code
// inside of onDraw()
mFadeOut.start();
mFadeOut.getTransformation(System.currentTimeMillis(), mTransformation);
invalidate();
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...existing drawing code...
canvas.drawBitmap(mCharacterBitmap, 0, 0, mCharacterPaint);
if (mFadeOut.hasStarted() && !mFadeOut.hasEnded()) {
mFadeOut.getTransformation(System.currentTimeMillis(), mTransformation);
//Keep drawing until we are done
mCharacterPaint.setAlpha((int)(255 * mTransformation.getAlpha()));
invalidate();
} else {
//Reset the alpha if animation is canceled
mCharacterPaint.setAlpha(255);
}
}
}
The most efficient way to dynamically modify the transparency of what you draw is to apply it using a Paint
drawing to your Canvas
. You will need to continually invalidate()
the view with each frame transition to get the animation to display until the character is gone. The example uses an Animation
object and a Transformation
object to handle all of the timing math to make the animation actually look good.
The gist here is that you start the animation via some external trigger (I wouldn't recommend doing the check for when to fade out in onDraw()
, probably better in the place where those character locations are updated. In my example, for simplicity sake, I started this when the view to touched.
This trigger starts the animation and gets the initial transformation value, then invalidate()
triggers a new onDraw()
. While the animation is running, onDraw()
is repeated due to the invalidate()
and each iteration the alpha on the paint decreases slightly.
When the animation is finished, it will call the AnimationListener
for you, so you can trigger the screen transition inside of onAnimationEnd()
.