2011-12-08 96 views
1

據推測它必須是相當普遍的願望的屏幕,其中 有圖形元素(您可能喜歡用帆布)和窗口小部件/按鈕在相同的屏幕上。但是,一切都我看到目前爲止給出要麼全控件OR整個屏幕畫布的屏幕的例子。有人能指出我的一些示例代碼,以便同時使用兩者。結合畫布和佈局?

...或者是這難道不是天經地義的事?

編輯:從史蒂夫的建議,下面就我的代碼現在看起來像這樣:

public class CanLay extends Activity 
{ 
    Bitmap bm; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.canlay); 

     InputStream is = getResources().openRawResource(R.drawable.ella); 
     bm = BitmapFactory.decodeStream(is); 

     SurfaceView sv; 
     SurfaceHolder sh; 
     Canvas can = null; 

     sv = (SurfaceView)findViewById(R.id.surview); 
     sh = sv.getHolder(); 

     try 
     { 
      can = sh.lockCanvas(null); 

      synchronized(sh) 
      { 
       can.drawBitmap(bm, 0, 0, null);   
      } 
     } 
     finally 
     { 
      if (can != null) 
      { 
       sh.unlockCanvasAndPost(can); 
      } 
     } 
    } 
} 

現在唯一的問題是,sh.lockCanvas(NULL);總是返回null。

回答

3

我不知道有什麼樣的代碼,但你通常從SurfaceView,這是一個View像其他小部件(如TextViewButton)得到了Canvas。我會嘗試只是佈局SurfaceView以及佈局的其他元素。將您的基本XML結構可能類似於

<LinearLayout > 
    <TextView /> 
    <Button /> 
    <SurfaceView /> 
</LinearLayout> 

編輯: 要獲得CanvasSurfaceView,先拿到SurfaceHolder,然後鎖定在畫布上,畫出你的東西,並解開帆布把它顯示。在代碼中,通常是這樣的:

SurfaceHolder holder = surfaceView.getHolder(); 
Canvas c = null; 
try { 
    c = holder.lockCanvas(null); 
    synchronized(holder) { 
     // draw here 
     // c.drawBitmap() or whatever 
    } 
} finally { 
    if(c != null) 
     holder.unlockCanvasAndPost(c); 
} 

DOUBLE編輯: 按照docs,當表面沒有準備好lockCanvas返回null。當你仍然在onCreate(),表面肯定沒有準備好。你知道一個表面準備的方法是通過處理一個回調SurfaceHolder.Callback.surfaceCreated()。 (遊戲經常使用surfaceCreated()知道什麼時候開始運行其非事件線程)。

我知道,這聽起來好像越來越多,你必須做的東西,但它真的不是那麼糟糕。你甚至可以這樣做內聯:

void onCreate(Bundle savedInstanceState) { 

    // inflate the XML with setContentView(), create your Bitmap, etc 

    sv = (SurfaceView)findViewById(R.id.surview); 
    sv.addCallback(new SurfaceHolder.Callback() { 
     @Override 
     void surfaceCreated(SurfaceHolder holder) { 
      Canvas can; 
      try { 
       can = holder.lockCanvas(null); 
       synchronized(holder) { 
        can.drawBitmap(bm, 0, 0, null);   
       } 
      } finally { 
       if(can != null) { 
        holder.unlockCanvasAndPost(can); 
      } 
     }}); 

    // the rest of onCreate() 
} 

我可能搞砸了一些大括號,但你明白了。總體而言,將您的SurfaceHolder.Callback實現放在自己的非惡意類中可能會更容易一些,因爲匿名是有限制的,但這是您知道SurfaceView已準備就緒的方式。當然,這是很好的落實SurfaceHolder.Callback.surfaceDestroyed(),讓你知道什麼時候SurfaceView是走出去的企業。 (遊戲經常使用surfaceDestroyed()來知道何時停止運行它們的非事件線程)

+0

謝謝,但是如何從surfaceview中獲取畫布? – Mick

+0

你可以在開始時只獲取一次'SurfaceHolder',然後每次你想要繪製'Canvas'就可以得到它。當然,你可以從'findViewById()'得到'SurfaceView'。 –

+0

我敢肯定,你的建議是正確的,但我還是一個一團糟短期得到它的工作的 - 見編輯。 – Mick