【问题标题】:Android cannot update SurfaceView in onCreate()?Android 无法在 onCreate() 中更新 SurfaceView?
【发布时间】:2012-08-10 21:04:14
【问题描述】:

我想要做的是创建一个带有 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 返回lockCanvas 调用为 null。

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

  • surface.paint() 放在onResume() 中 - 结果相同。
  • 覆盖表面 draw(Canvas),然后在那里绘制 - 不走运。
  • 在绘图前对 Canvas 进行空值检查 - 没有例外,但是, 没有任何东西被绘制,就像没有 surface.paint() 在 onCreate()

我真的不知道为什么会这样,否则一切似乎都正常。

【问题讨论】:

    标签: android canvas surfaceview


    【解决方案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 中进行空检查。

    【讨论】:

    • 嘿!谢谢,但我实际上是在 SurfaceView 中进行绘图的。当我查看列表时,Eclipse 甚至没有为我提供这些功能来覆盖。这些方法属于哪些类?
    • 抱歉,我遗漏了一条重要信息。这些方法属于 SurfaceHolder.Callback。实现它并在构造函数中将surfaceView设置为它自己的回调。
    • 今天的英雄 :D 非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多