1. 程式人生 > >Android Canvas元件例項

Android Canvas元件例項

本文是翻譯自一篇英文教程Android Canvas Example,讀者可以到原文章地址中下載原始碼。在原文中,作者已經修改了在canvas上畫圖是程式崩潰的bug,我相信這個對初學者是一個非常好的學習例項。

Android系統提供一系列的影象介面,滿足了大多數應用的需求。我們可以使用2D影象庫和OpenGL ES1.0的3D函式庫。在這片例項教程中,我們將討論如何使用2D圖形顯示影象。在Android中,我們可以使用兩種方式實現2D影象顯示:

  1. 在layout xml檔案中定義View物件
  2. 使用2D影象庫直接在Canvas上繪製圖像
舉個例子,我們想顯示一張圖片在android螢幕上,我們可以再layout xml檔案中定義ImageView物件來顯示圖片,也可以將圖片載入到Bitmap物件中,然後繪製到Canvas上顯示。使用何種發放取決於實際需求。本文中,講簡要介紹如何把圖片載入到Bitmap物件中,並且畫到canvas物件上。

在canvas物件上畫圖,一般使用onDraw()回撥函式,我們可以使用SurfaceHolder.lockCanvas()來的到canvas。

public class DrawCanvas extends SurfaceView implements Callback {
private CanvasThread canvasThread;
 
public DrawCanvas(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
 
public DrawCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
 
this.getHolder().addCallback(this);
this.canvasThread = new CanvasThread(getHolder());
this.setFocusable(true);
}
 
public DrawCanvas(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
 
}
 
public void startDrawImage() {
canvasThread.setRunning(true);
canvasThread.start();
}
 
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
 
}
 
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
 
}
 
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
boolean retry = true;
canvasThread.setRunning(false);
while(retry) {
try {
canvasThread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Bitmap sweet = BitmapFactory.decodeResource(getResources(), R.drawable.sq);
canvas.drawColor(color.black);
canvas.drawBitmap(sweet, 0, 0, null);
}
 
private class CanvasThread extends Thread {
private SurfaceHolder surfaceHolder;
private boolean isRun = false;
 
public CanvasThread(SurfaceHolder holder) {
this.surfaceHolder = holder;
}
 
public void setRunning(boolean run) {
this.isRun = run;
}
 
@Override
public void run() {
// TODO Auto-generated method stub
Canvas c;
 
while(isRun) {
c = null;
try {
c = this.surfaceHolder.lockCanvas(null);
synchronized(this.surfaceHolder) {
DrawCanvas.this.onDraw(c);
}
} finally {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}

DrawCanvas繼承了SurfaceView類,並且實現了Callback介面。在類定義中,畫圖的主要部分是onDraw函式。這個函式在一個執行緒CanvasThread中被呼叫。有興趣的朋友可以到源地址中下載原始碼來執行程式。