2011-12-08 4 views
1

(キャンバスを使用したいかもしれない)グラフィックス要素とウィジェット/ボタンが同じ画面にあるスクリーンを望むのはかなり一般的です。しかし、私が今まで見てきたことのすべては、ウィジェットでいっぱいのスクリーンの例を示していますまたは全画面キャンバス。誰かが両方を同時に使用するためのいくつかのサンプルコードを指し示すことができますか?キャンバスとレイアウトを結合しますか?

...これは行われたものではありませんか?

EDIT:はスティーブの提案に続いて私のコードは次のようになります。

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

私は、任意のサンプルコードを知りませんが、通常は他のウィジェット(例えば、TextViewButton)などのViewあるSurfaceViewからCanvasを取得します。 SurfaceViewとレイアウトの他の要素をレイアウトしてみます。 、SurfaceViewからCanvasを取得する最初のSurfaceHolderを取得し、その後、キャンバスをロックし、自分のものを描き、それが表示され持っているキャンバスのロックを解除するには :あなたの基本的なXML構造が

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

EDITのようになります。 。

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 EDIT:通常のようなコードでは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()を実装するのは良いことです。 (ゲームでは多くの場合、イベント以外のスレッドの実行を停止する方法を知るためにsurfaceDestroyed()を使用しています)。

+0

ありがとうございます。しかし、どのように表面ビューからキャンバスを取得しますか? – Mick

+0

最初に 'SurfaceHolder'を一度取得し、描画するたびに' Canvas'を取得することができます。もちろん、 'findViewById()'から 'SurfaceView'を取得します。 –

+0

私はあなたの提案が正しいと確信していますが、私はまだそれを動作させるのに手近ではありません。 – Mick

関連する問題