Android - Fade out bitmap image on canvas

前端 未结 3 1543
闹比i
闹比i 2021-02-08 22:53

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

3条回答
  •  长情又很酷
    2021-02-08 23:29

    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().

提交回复
热议问题