0

私がやろうとしているのは、SurfaceViewを使用して描画アプリを作成することです。私のアプリは基本的に完成していますが、1つ欠けていることがあります。それは、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
}

そして、アクティビティの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メソッドも呼び出します。

すべてのペイントは、SurfaceViewの外部で呼び出されることのないdoDrawメソッドで行われます。また、何かを描画する前に、CanvasオブジェクトのdoDrawでnullチェックを実行してください。

于 2012-08-10T21:40:13.470 に答える