Android SurfaceView不保留先前绘制的对象 [英] Android SurfaceView not retaining previously drawn objects

查看:369
本文介绍了Android SurfaceView不保留先前绘制的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试SurfaceView.我的要求是先简单地渲染一个节点(简单的可绘制对象).然后,在以后的某个时间点渲染更多节点.

I am experimenting with SurfaceView. My requirement is to simply render a node (simple drawable) first. Then, render more nodes at a later point in time.

我的线程的运行方法&的代码段我的doDraw方法如下.我只是想在随后的传递中渲染2个不同的可绘制对象,同时保留两者.问题是它擦除了第一遍中写入的所有内容(请参见代码中的注释). 如何保留先前绘制的对象?

The snippets of my thread's run method & my doDraw method are below. I am just trying to render 2 different drawables in subsequent passes while retaining both. The problem is it wipes away whatever gets written in 1st pass (see comment in code). How to retain the previously drawn object?

    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: 仍然似乎不起作用.我将运行代码更改为通过非:

UPDATE 1: Still does not seem to work. I changed the run code to this passing a non:

     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传递给脏矩形.尚无法使用...

Later I tried passing 0,0,1,1 to dirty rectangle. Could not get it to work yet...

推荐答案

SurfaceView具有双缓冲或三缓冲.先前的内容是保留的",即系统不会竭尽全力清除较旧的缓冲区,但是您不能依靠该行为.

The SurfaceView is double- or triple-buffered. The previous contents are "preserved" in the sense that the system doesn't go out of its way to clear older buffers, but you can't rely on that behavior.

如果您指定脏矩形,则框架将渲染您所要求的内容,然后从新缓冲区顶部的上一个缓冲区复制非脏区域.

If you specify a dirty rect, the framework will render whatever you ask, then copy the non-dirty region from the previous buffer on top of the new buffer.

允许系统扩展脏矩形-您传递给lockCanvas()的Rect可能会更新.您需要重新绘制其中的每个像素.

The system is allowed to expand the dirty rectangle -- the Rect you pass to lockCanvas() may be updated. You're required to redraw every pixel inside it.

有关此操作的示例(令人耳目一新),请参见 Grafika .

For a (somewhat eye-searing) example of this in action, see "Simple Canvas in TextureView" in Grafika.

有关系统工作方式的更多详细信息,请参见本文.

For more details on how the system works, see this article.

这篇关于Android SurfaceView不保留先前绘制的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆