我正在尝试使用SurfaceView。我的要求是首先简单地渲染一个节点(简单的drawable)。然后,在稍后的时间点渲染更多节点 。
我线程的运行方法和片段的片段我的doDraw方法如下。我只想在后续传球中渲染2个不同的抽签,同时保留两者。问题是它消除了第一遍中写入的内容(请参阅代码中的注释)。 如何保留以前绘制的对象?
public void run() {
Canvas canvas;
while (_running) {
canvas = null;
try {
canvas = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
doDraw(canvas, isUpdate);
}
} finally {
if (canvas != null) {
_surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
public void doDraw(Canvas canvas, boolean update){
if(update){
//goes here 2nd pass & wipes away things done in 1st pass
//I want to retain whatever was drawn in 1st pass
Bitmap thumb = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
//canvas.drawColor(Color.RED);
canvas.drawBitmap(thumb, 0, 0, null);
} else{
//goes here 1st pass
Bitmap thumb = BitmapFactory.decodeResource(getResources(), R.drawable.thumb);
//canvas.drawColor(Color.BLACK);
canvas.drawBitmap(thumb, 300, 300, null);
this.isUpdate = true;
}
}
更新1: 似乎仍然没有奏效。我将运行代码更改为通过非:
public void run() {
Canvas canvas;
while (_running) {
canvas = null;
try {
Rect dty = null;
if(isUpdate == true){
//--> In 2nd pass, I was hoping that only these co-ordinates will be updated
dty = new Rect(0,0,100,100);
canvas = _surfaceHolder.lockCanvas(dty);
}else{
canvas = _surfaceHolder.lockCanvas(null);
}
synchronized (_surfaceHolder) {
doDraw(canvas, isUpdate);
}
} finally {
if (canvas != null) {
_surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
后来我尝试将0,0,1,1传递给脏矩形。无法让它工作......
答案 0 :(得分:0)
我在Android documentation中找到了这个有趣的注释:
在unlockCanvas()之间永远不会保留Surface的内容 和lockCanvas(),因此,Surface区域内的每个像素 必须写。这个规则的唯一例外是脏的时候 指定了矩形,在这种情况下,将使用非脏像素 保留。
所以要做你想做的事情,看起来你需要在lockCanvas
电话中提供一个非空的脏矩形。此外,只有当您的节点像素都不相交时,这才会起作用。
答案 1 :(得分:0)
SurfaceView是双缓冲或三缓冲。之前的内容是"保留"从某种意义上说,系统并不是为了清除旧缓冲区,但你不能依赖这种行为。
如果指定了一个脏矩形,框架将呈现您提出的任何内容,然后从新缓冲区顶部的前一个缓冲区中复制非脏区域。
允许系统扩展脏矩形 - 可以更新传递给lockCanvas()
的Rect。您需要重新绘制其中的每个像素。
对于这个(有点眼睛灼热)的例子,请参阅" TextureView中的简单画布"在Grafika。
有关系统工作原理的详细信息,请参阅this article。