50 Android Hacks Hack7 在canvas上绘制动画
2014-10-21 15:19
363 查看
《50 Android Hacks 》这本书讲解了Android的50个小技巧,大家有空可以看看,也有不少人翻译。
书中源码作者奇托在:
Macarse/50AH-code · GitHub
https://github.com/Macarse/50AH-code
下面就按照我的理解逐一翻译一下
Hack 7 在canvas上绘制动画
我们要给控件实现动画效果,首先想到的是Android 的动画api,帧动画,补间动画,属性动画等,那我们那我们能不能直接画一个动画效果呢?
利用Canvas的刷新操作,对canvas不理解的可以查查资料,我们可以实现移动的动画,下面来实现一个在屏幕中随意移动的动画:
首先要准备一张画布,把画布放到我们的窗口中,还要准备一张移动的方块,当然方块我们也可以用paint自己画,这就要再套一层
为了实现画布,要扩展view,覆写onDraw(Canvas canvas)方法
小方块是一个独立的视图,这里不把小方块显示在activity中,在它外面又“包”了一层
画布代码:
Rectangle就是屏幕中移动的红色方块,也可以放一张图片在屏幕中移动
Rectangle继承View类,重写onDraw()方法,并提供一些setter和getter方法,用于设置小方块的属性。判断碰撞事件的逻辑在moveTo()方法中。
Rectangle实现代码:
当onDraw()方法被调用的时候,我们将会改变小方块的位置然后将它绘制到画布上。这里的invalidate()就是这个Hack的关键,这个函数的作用就是强制一个View进行绘制(即调用onDraw方法)。因此将invalidate()方法放到onDraw()方法里面就意味着每当View绘制完自己的时候就会马上调用invalidate()进行再次绘制。换个角度来看,我们其实就是在循环的调用小方块的move()方法和onDraw()方法来创建一个有趣的动画。
提示:
在onDraw()方法里面调用invalidate()方法来更新view的位置是创建动画的一种很简单的途径。如果做一个小游戏,用这个方式可以实现循环
源码大家去github上下载
点击打开链接
待续。。。。
书中源码作者奇托在:
Macarse/50AH-code · GitHub
https://github.com/Macarse/50AH-code
下面就按照我的理解逐一翻译一下
Hack 7 在canvas上绘制动画
我们要给控件实现动画效果,首先想到的是Android 的动画api,帧动画,补间动画,属性动画等,那我们那我们能不能直接画一个动画效果呢?
利用Canvas的刷新操作,对canvas不理解的可以查查资料,我们可以实现移动的动画,下面来实现一个在屏幕中随意移动的动画:
首先要准备一张画布,把画布放到我们的窗口中,还要准备一张移动的方块,当然方块我们也可以用paint自己画,这就要再套一层
为了实现画布,要扩展view,覆写onDraw(Canvas canvas)方法
小方块是一个独立的视图,这里不把小方块显示在activity中,在它外面又“包”了一层
画布代码:
package com.example.canvasanimation; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.view.View; public class DrawView extends View { private Rectangle mRectangle; public int width; public int height; public DrawView(Context context) { super(context); mRectangle = new Rectangle(context, this); mRectangle.setARGB(255, 255, 0, 0); mRectangle.setSpeedX(3); mRectangle.setSpeedY(3); } //覆写 onDraw,在画布上操作 @Override protected void onDraw(Canvas canvas) { invalidate(); mRectangle.move(); //矩形在同一块画布上画,mRectance外面又包了一层画布,为同一个画布 mRectangle.onDraw(canvas); } }
Rectangle就是屏幕中移动的红色方块,也可以放一张图片在屏幕中移动
Rectangle继承View类,重写onDraw()方法,并提供一些setter和getter方法,用于设置小方块的属性。判断碰撞事件的逻辑在moveTo()方法中。
Rectangle实现代码:
package com.example.canvasanimation; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.view.View; public class Rectangle extends View { public static final int MAX_SIZE = 40; private static final int ALPHA = 255; private int mCoordX = 0; private int mCoordY = 0; private int mRealSize = 40; private int mSpeedX = 3; private int mSpeedY = 3; private boolean goRight = true; private boolean goDown = true; private DrawView mDrawView; private Paint mInnerPaint; private RectF mDrawRect; public Rectangle(Context context, DrawView drawView) { super(context); mDrawView = drawView; mInnerPaint = new Paint(); mDrawRect = new RectF(); /* Red is default */ mInnerPaint.setARGB(ALPHA, 255, 0, 0); mInnerPaint.setAntiAlias(true); } public void setARGB(int a, int r, int g, int b) { mInnerPaint.setARGB(a, r, g, b); } public void setX(int newValue) { mCoordX = newValue; } public float getX() { return mCoordX; } public void setY(int newValue) { mCoordY = newValue; } public float getY() { return mCoordY; } public void move() { moveTo(mSpeedX, mSpeedY); } private void moveTo(int goX, int goY) { // check the borders, and set the direction if a border has reached if (mCoordX > (mDrawView.width - MAX_SIZE)) { goRight = false; } if (mCoordX < 0) { goRight = true; } if (mCoordY > (mDrawView.height - MAX_SIZE)) { goDown = false; } if (mCoordY < 0) { goDown = true; } // move the x and y if (goRight) { mCoordX += goX; } else { mCoordX -= goX; } if (goDown) { mCoordY += goY; } else { mCoordY -= goY; } } public int getSpeedX() { return mSpeedX; } public void setSpeedX(int speedX) { mSpeedX = speedX; } public int getmSpeedY() { return mSpeedY; } public void setSpeedY(int speedY) { mSpeedY = speedY; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设定 矩形的大小,参数为左上右下边界 mDrawRect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY + mRealSize); //画圆角矩形。第一个5为x轴半径,第二个5为y轴半径 canvas.drawRoundRect(mDrawRect, 5, 5, mInnerPaint); } public void setSize(int newSize) { mRealSize = newSize; } public int getSize() { return mRealSize; } }最后把画布放到我们的窗口当中:
package com.example.canvasanimation; import android.os.Bundle; import android.app.Activity; import android.view.Display; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { private DrawView mDrawView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //获取窗口展示,包含窗口的宽度,长度 Display display = getWindowManager().getDefaultDisplay(); //初始化DrawView mDrawView = new DrawView(this); //将窗口的宽高,赋值给mDrawView的宽高,使其充满整个窗口 mDrawView.height = display.getHeight(); mDrawView.width = display.getWidth(); //把窗口设为activity的布局 setContentView(mDrawView); } }
当onDraw()方法被调用的时候,我们将会改变小方块的位置然后将它绘制到画布上。这里的invalidate()就是这个Hack的关键,这个函数的作用就是强制一个View进行绘制(即调用onDraw方法)。因此将invalidate()方法放到onDraw()方法里面就意味着每当View绘制完自己的时候就会马上调用invalidate()进行再次绘制。换个角度来看,我们其实就是在循环的调用小方块的move()方法和onDraw()方法来创建一个有趣的动画。
提示:
在onDraw()方法里面调用invalidate()方法来更新view的位置是创建动画的一种很简单的途径。如果做一个小游戏,用这个方式可以实现循环
源码大家去github上下载
点击打开链接
待续。。。。
相关文章推荐
- Android view利用canvas绘制动画(一)
- Android中使用SurfaceView和Canvas来绘制动画
- Android中使用SurfaceView和Canvas来绘制动画
- Android中使用SurfaceView和Canvas来绘制动画
- Android(小画板) Canvas中绘制基本图形时的小结
- android canvas绘制折线图和柱状图
- Android画布和图形绘制---Canvas and Drawables(二)
- Android画布和图形绘制---Canvas and Drawables(三)
- android 通过canvas旋转 绘制文字 竖直等不同方向的显示
- Android上使用Canvas绘制文字
- Android上使用Canvas绘制文字
- android游戏引擎andengine学习系列四:绘制特效的动画文字
- Android开发:canvas.drawTextOnPath()无效----Android4.03的又一个bug!!!!(关于Canvas绘制的方方面面) .
- Android开发--图形图像与动画(一)--Paint和Canvas类
- Android开发:ImageView上绘制旋转圆环(透明度不同的旋转圆环,利用canvas.drawArc实现)
- Android画布和图形绘制---Canvas and Drawables
- Android画布和图形绘制---Canvas and Drawables(一)
- android中使用Canvas绘制指定位置和宽高度的图片
- Android画布和图形绘制---Canvas and Drawables(五)
- android中使用Canvas绘制指定位置和宽高度的图片