Android 中的Canvas 可以在屏幕上绘图,定义是这样的:
“可以把 Canvas 视为 Surface 的替身或者接口,图形便是绘制
在 Surface 上的。 Canvas 封装了所有绘图调用。通过 Canvas,绘制
到 Surface 上的内容首先存储到与之关联的 Bitmap 中,该 Bitmap
最终会呈现到窗口上。”
Canvas 类封装了所有绘图调用,可以创建一个 View(视图),重写其 onDraw() 方法,在该方法中便可以绘制基本的图形单元
效果图
步骤
首先创建一个方块类
public class Rectangle extends View {
public static final int MAX_SIZE = 140;
private static final int ALPHA = 255;
private int mCoordX = 0;
private int mCoordY = 0;
private int mRealSize = 140;
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);
canvas.drawRoundRect(mDrawRect, 0, 0, mInnerPaint);
}
public void setSize(int newSize) {
mRealSize = newSize;
}
public int getSize() {
return mRealSize;
}
}
在主界面显示的内容视图
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(10);
mRectangle.setSpeedY(10);
}
@Override
protected void onDraw(Canvas canvas) {
invalidate();//重绘View
mRectangle.move();//变换方块位置
mRectangle.onDraw(canvas);//将方块绘制到Canvas上
}
}
主界面
public class Hack07Activity extends Activity {
private DrawView mDrawView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();//获取屏幕的宽和高
mDrawView = new DrawView(this);
mDrawView.height = display.getHeight();
mDrawView.width = display.getWidth();
setContentView(mDrawView);
}
}
一点说明:invalidate() 方法本身就是一个小技巧,这个方法强制重绘视图。把这个方法放在 onDraw() 的目的是为了在 View 绘制完自身后,可以立即重新调用 onDraw() 方法。换句话说,通过循环调用Rectangle 的 move() 和 onDraw() 方法实现一个动画效果。