Android – 在canvas上淡出位图图像

我正在绘制缩放的位图到canvas上,并希望在特定的时间淡出我的图像

基本上,当我的angular色图像超过了canvas的某个部分时,我需要angular色图像慢慢消失(3秒),然后页面自动redirect到下一个Java类。

目前,我的图像只是redirect到新的Java类,请参阅下面的代码来创build我的图像。

Resources res = getResources(); float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, res.getDisplayMetrics()); imgSpacing = (int) px / 2; int size = (int) ((PhoneWidth / 5) - px); chrImg = BitmapFactory.decodeResource(getResources(), R.drawable.character); chrImg = Bitmap.createScaledBitmap(chrImg, size, size, true); 

然后在canvas上的onDraw:

 if(indexX == mazeFinishX && indexY == mazeFinishY) { canvas.drawBitmap(finish, j * totalCellWidth, i * totalCellHeight, null); // As soon as the character moves over this square they are automatically re-directed to new page // This is where I want to fade the character image out before the re-direct } 

我已经在网上看,但不能完全弄清楚如何让我从我的游戏资源可绘制文件夹中提取的可绘制图像的衰落工作。 谢谢

如果你认为有可能你想要改变淡入淡出的animation,如缩放和/或旋转,那么你应该使用animationXML。

但是,对于快速位图淡入淡出,您可以重复张贴延迟的无效消息。 你可能想限制你的失效区域,只是你的人物位图的位置:

 private static final int FADE_MILLISECONDS = 3000; // 3 second fade effect private static final int FADE_STEP = 120; // 120ms refresh // Calculate our alpha step from our fade parameters private static final int ALPHA_STEP = 255 / (FADE_MILLISECONDS / FADE_STEP); // Initializes the alpha to 255 private Paint alphaPaint = new Paint(); // Need to keep track of the current alpha value private int currentAlpha = 255; @Override protected void onDraw(Canvas canvas) { ... if(indexX == mazeFinishX && indexY == mazeFinishY) { // Drawing your wormhole? int x = j * totalCellWidth; int y = i * totalCellHeight; canvas.drawBitmap(finish, x, y, null); if (currentAlpha > 0) { // Draw your character at the current alpha value canvas.drawBitmap(chrImg, x, y, alphaPaint); // Update your alpha by a step alphaPaint.setAlpha(currentAlpha); currentAlpha -= ALPHA_STEP; // Assuming you hold on to the size from your createScaledBitmap call postInvalidateDelayed(FADE_STEP, x, y, x + size, y + size); } else { // No character draw, just reset your alpha paint currentAlpha = 255; alphaPaint.setAlpha(currentAlpha); // Now do your redirect } } ... } 

我build议将常量FADE_MILLISECONDS和FADE_STEP放到res / integers.xml中,以便它们不是硬编码的。

我解释这个最好的方法是提供一个完整的自定义视图的例子,你可以从你需要的东西拉。 以下是完成这个的一个视图。

 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 (PS 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); } } } 

dynamic修改绘制的透明度的最有效方法是使用“ Paintgraphics将其应用于“ Canvas 。 您将需要不断invalidate()每个帧过渡invalidate()视图,以获取animation显示,直到字符消失。 该示例使用一个Animation对象和一个Transformation对象来处理所有的计算math,以使animation看起来不错。

这里的要点是,你通过一些外部的触发器开始animation(我不build议检查什么时候在onDraw()淡出,在这些字符位置更新的地方可能会更好。在我的例子中,为了简单为了这个缘故,我在这个时候开始感动。

这个触发器启动animation并获得初始转换值,然后invalidate()触发一个新的onDraw() 。 在animation运行时,由于invalidate()和每次迭代, onDraw()都会重复,所以paint上的alpha会略微减less。

当animation完成后,它会为你调用AnimationListener ,所以你可以触发onAnimationEnd()的画面转换。

  if(indexX == mazeFinishX && indexY == mazeFinishY) { canvas.drawBitmap(finish, j * totalCellWidth, i * totalCellHeight, null); // As soon as the character moves over this square they are automtically re-directs to new page new CountDownTimer(0500, 1000) { @Override public void onTick(long millisUntilFinished) {} @Override public void onFinish() { Paint paint = new Paint(); paint.setAlpha(25); canvas.drawBitmap(chrImg, 0, 0, paint); } }.start(); new CountDownTimer(0500, 1000) { @Override public void onTick(long millisUntilFinished) {} @Override public void onFinish() { Paint paint = new Paint(); paint.setAlpha(45); canvas.drawBitmap(chrImg, 0, 0, paint); } }.start(); new CountDownTimer(0500, 1000) { @Override public void onTick(long millisUntilFinished) {} @Override public void onFinish() { Paint paint = new Paint(); paint.setAlpha(70); canvas.drawBitmap(chrImg, 0, 0, paint); } }.start(); new CountDownTimer(0500, 1000) { @Override public void onTick(long millisUntilFinished) {} @Override public void onFinish() { Paint paint = new Paint(); paint.setAlpha(100); canvas.drawBitmap(chrImg, 0, 0, paint); } }.start(); // This is where I want to fade the cahracter image out before the re-direct new CountDownTimer(3000, 1000) { @Override public void onTick(long millisUntilFinished) { // TODO Auto-generated method stub } @Override public void onFinish() { // TODO Auto-generated method stub Intent i = new Intent(currentclass.this, nextClass.class); startActivity(i); } }.start(); } 

这将使你的位图变得透明(alpha将是100),然后在3秒后redirect到下一个类。

更新:对于位图你不能使用.setAlpha所以我们必须使用一个油漆,所以我们每次创build一个新的油漆,然后设置与油漆的位图。 但如果你有一个imageView,你可以使用.setalpha