本文來自人人網android開發交流羣
大家常撰寫View的子類別,然後在其onDraw()函數裏繪出各式各樣的圖形,例如畫出點或是直線。不過,基本上onDraw()函數是在Canvas畫完所有線條等圖形後,才一塊兒將Canvas顯示出來。
然而,當我們想再畫出一些線條之後,停個幾秒鐘之後,才繼續繪出後續的圖形,這種有停頓的計時性繪圖,又該如何呢?
例如,先繪出一條綠色線段:
停頓5秒鐘之後,才畫出一條黃色線段:
這時,使用SurfaceView會是一個好方法。
SurfaceView類是一個特別的View子類,在遊戲中經常被使用,速度要比一般的View快幾倍。
它和View類的主要區別在於它的描繪工作在輔助線程中完成,不佔用主線程;而普通View類的描繪在主線程中完成。
需要實現SurfaceHolder.Callback接口,以對其進行創建,銷燬,改變時的情況進行監視。
如下之範例程序代碼:
package com.misoo.ppvv;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
public class ac01 extends Activity {
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
MySurfaceView mv = null;
try {
mv = new MySurfaceView(this);
} catch (InterruptedException e) {
e.printStackTrace();
}
//----------------------------------
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(200, 150);
param.topMargin = 5;
layout.addView(mv, param);
//----------------------------------------
setContentView(layout);
}
}
package com.misoo.ppvv;
import android.content.Context;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
private DrawThread mThread;
private dwList dwl;
MySurfaceView(Context context) throws InterruptedException {
super(context);
getHolder().addCallback(this);
dwl = new dwList();
dwl.begin_record();
dwl.record(30, 30, 0, 0);
dwl.record(100, 100, 1, Color.GREEN);
Thread.sleep(50);
dwl.record(100, 30, 1, Color.YELLOW);
Thread.sleep(60);
dwl.record(30, 30, 1, Color.BLUE);
Thread.sleep(40);
dwl.record(30, 100, 1, Color.RED);
}
public void surfaceCreated(SurfaceHolder holder) {
mHolder = holder;
mThread = new DrawThread();
mThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
mThread = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
}
// ----------------------------------------------------------------------
class DrawThread extends Thread {
DrawThread() {
super();
}
@Override
public void run() {
dwl.draw(mHolder);
}
}
}
package com.misoo.ppvv;
import java.util.ArrayList;
import java.util.Iterator;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;
public class dwList {
private Paint paint= null;
private long draw_time;
private ArrayList<dwPoint> poList;
public void begin_record()
{
dwPoint.initial_time = System.currentTimeMillis();
poList.clear();
}
public void record(int x, int y, int ty, int color)
{ dwPoint po = new dwPoint(x, y, ty, color);
poList.add(po);
}
public dwList(){
paint = new Paint();
poList = new ArrayList<dwPoint>();
}
public void draw(SurfaceHolder holder) {
dwPoint po;
long curr_time;
long base_time =0;
int nnn = 0;
Iterator<dwPoint> it = poList.iterator();
while (it.hasNext() ){
po = it.next();
draw_time = po.m_timeSpan * 100;
if(nnn == 0)
base_time = System.currentTimeMillis();
nnn++;
//--------- waiting ----------------------------------
do {
curr_time = System.currentTimeMillis() - base_time;
}
while (curr_time < draw_time);
//------------------------------------------------------
paint(holder, nnn );
}
}
public void paint(SurfaceHolder holder, int k) {
Canvas canvas = holder.lockCanvas();
dwPoint po;
int lastX = 0;
int lastY = 0;
Iterator<dwPoint> it = poList.iterator();
for (int i = 0; i<k; i++) {
po = it.next();
if(po.m_type == 0 ) {
lastX = po.m_x;
lastY = po.m_y;
}
else {
paint.setColor(po.m_color);
paint.setStrokeWidth(3);
canvas.drawLine(lastX, lastY, po.m_x, po.m_y, paint);
lastX = po.m_x;
lastY = po.m_y;
}
}
holder.unlockCanvasAndPost(canvas);
}
}
package com.misoo.ppvv;
public class dwPoint {
public static long initial_time;
public int m_x, m_y, m_type;
public long m_timeSpan;
public int m_color;
public dwPoint() {}
public dwPoint(int x, int y, int ty, int cc) {
m_x = x;
m_y = y;
m_type = ty;
m_color = cc;
m_timeSpan = (long)(System.currentTimeMillis() - initial_time);
}