我曾经在onDraw方法中使用ImageView进行绘图。然而,我学到了最好将画布绘制在onDraw之外,并只在onDraw中更新画布。
我知道这显然是错误的(因为它不起作用),但我该如何实现我想做的事情:
@Override
public void onDraw(Canvas c) {
c = this.newCanvas;
super.onDraw(c);
}
我曾经在onDraw方法中使用ImageView进行绘图。然而,我学到了最好将画布绘制在onDraw之外,并只在onDraw中更新画布。
我知道这显然是错误的(因为它不起作用),但我该如何实现我想做的事情:
@Override
public void onDraw(Canvas c) {
c = this.newCanvas;
super.onDraw(c);
}
画布只是用于在某个东西上绘制的句柄--你需要获取该东西本身。在onDraw()之外绘制的画布需要由位图支持。然后在onDraw()中,只需将该位图绘制到提供的画布中:
Bitmap my_bitmap = null; /* this needs to be initialized whereever it is drawn into */
@Override
public void onDraw(Canvas c) {
if (my_bitmap != null) {
c.drawBitmap(my_bitmap, 0.0, 0.0, null);
}
}
onSizeChanged()是初始化Bitmap的合适位置,因为这样你就知道了它的大小:
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
my_bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
要在my_bitmap上绘制,只需使用以下代码创建一个新的Canvas:
Canvas c = new Canvas(my_bitmap);
public class GameLoopThread extends Thread {
private GameView view;
private boolean running = false;
public GameLoopThread(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
@Override
public void run() {
while (running) {
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
if (c != null) {
view.onDraw(c);
}
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
try {
sleep(10);
} catch (Exception e) {}
}
}
}
在您的活动中创建该线程,然后执行以下操作
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(new GameView(GameActivity.this));
}
然后在GameViewClass中做类似于这样的事情
public class GameView extends SurfaceView {
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
@Override
protected void onDraw(Canvas canvas) {
//Do Drawing
}
}
@Override
public void onDraw(Canvas c) {
c = this.getHolder().lockCanvas();
if (c != null) {
//draw on canvas
}
if (c != null) {
this.getHolder().unlockCanvasAndPost(c);
}
}
我不确定最后那一部分是否有效,从未测试过。 另外,如果你想在onDraw方法之外进行绘图,可以在一个线程中运行更新(在画布上绘制),并且每次调用onDraw方法时都检查画布是否准备好发布。例如,让你的线程有一个布尔值,一旦画布被拉出来就将其设置为false,这样线程就会为你绘制一个新的画布,但是一旦完成绘制就将布尔值设置为true。在ondraw方法中检查布尔值是否为true,如果是则拉出画布。