0

我想要做的是创建一个带有 SurfaceView 的绘图应用程序。我的应用程序基本上完成了,但缺少一件事:我无法让 SurfaceView 在其活动的 onCreate 中绘制自己。

我的SurfaceView派生类看起来像这样(只是重要的部分):

class DrawingSurface extends SurfaceView implements OnTouchListener
{ 
    SurfaceHolder holder;
    public DrawingSurface(Context context)
    {
        super(context);
        holder = getHolder();
    }
    // this method does the painting.
    public void paint()
    {
        Canvas canvas = holder.lockCanvas();
        //draw a bunch of stuff
        holder.unlockCanvasAndPost(canvas);
    }

    //in the onTouch method i call the paint() without any problem
}

以及 Activity 的 onCreate:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    surface = new DrawingSurface(this);
    setContentView(surface);
    //surface.paint(); <--- here is the problem
}

所以你可以看到代码是非常标准的,但是如果我尝试在 onCreate() 中使用 surface.paint(),那么我会得到一个NullPointerException,因为那时,调用SurfaceHolder返回 null lockCanvas

那么我该如何解决这个问题呢?我希望这个绘制方法在活动开始时运行,否则只有在用户开始绘制时才会绘制背景。我尝试了什么:

  • 放置- 相同surface.paint()onResume()结果。
  • 覆盖表面draw(Canvas),并在那里绘制 - 没有运气。
  • 在绘制之前对 Canvas 进行 nullcheck - 没有例外,但是没有绘制任何内容,就像在 onCreate() 中没有 surface.paint()

我真的不知道为什么会发生这种情况,否则一切似乎都有效。

4

1 回答 1

1

尝试不同的模型。在 SurfaceView 内完成所有绘画

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
    public DrawingSurface(Context context) {
        super(context);
        getHolder().addCallback(this);
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
        updatePanel();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        updatePanel();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        updatePanel();
    }

    public void updatePanel() {
        Canvas canvas = null;
        try {
            canvas = getHolder().lockCanvas(null);
            synchronized (getHolder()) {
                doDraw(canvas);
            }
        }
        finally {
            if (canvas != null) {
                getHolder().unlockCanvasAndPost(canvas);
            }
        }
    }
}

您还可以在触摸侦听器中调用 updatePanel 方法。

你所有的绘画都在 doDraw 方法中,它永远不会在 SurfaceView 之外调用。此外,请确保在尝试绘制任何内容之前在 Canvas 对象的 doDraw 中进行空检查。

于 2012-08-10T21:40:13.470 回答