2011-12-08 4 views
1

(캔버스를 사용하고 싶을 수도있는) 그래픽 요소와 위젯/단추가 같은 화면에있는 화면을 원한다면 꽤 일반적 일 것입니다. 하지만 지금까지 살펴본 모든 내용은 위젯으로 가득 찬 화면이나 예를 들어 또는 전체 화면 캔버스의 예를 보여줍니다. 다른 사람이 동시에 두 가지를 사용하기위한 몇 가지 예제 코드를 가리킬 수 있습니까?캔버스와 레이아웃을 결합 하시겠습니까?

... 아니면이 일이 아닌가요?

편집 : 스티브의 제안에 이어 내 코드는 이제 다음과 같습니다

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) 같은 ViewSurfaceView,에서 Canvas를 얻을. 레이아웃의 다른 요소들과 함께 SurfaceView을 배치 해보려고합니다. 당신의 기본적인 XML 구조처럼 보일 수

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

편집 : 가 얻을 수있는 CanvasSurfaceView에서 먼저 SurfaceHolder은, 다음, 캔버스를 잠글 물건을 그리고이를 표시하도록 캔버스 잠금을 해제 할 수 . docs에 따르면, lockCanvas NULL을 반환 표면이 준비되지 않은 경우 :

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 편집 : 코드에서이 정상적으로처럼 보인다. 여전히 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 구현을 자체의 비 이명 (non-anoymous) 클래스에 두는 것이 더 쉬울 수도 있지만 SurfaceView은 비즈니스 준비가 된 것입니다. SurfaceView이 언제 사는지 알 수 있도록 SurfaceHolder.Callback.surfaceDestroyed()을 구현하는 것이 좋습니다. (게임은 종종 surfaceDestroyed()을 사용하여 비 이벤트 스레드의 실행을 중지해야합니다.)

+0

감사합니다.하지만 어떻게 표면보기에서 캔버스를 얻을 수 있습니까? – Mick

+0

처음에는 'SurfaceHolder'를 한 번 가져올 수 있습니다. 그 다음에 그릴 때마다 'Canvas'를 얻을 수 있습니다. 물론 findViewById()에서'SurfaceView'를 얻을 수 있습니다. –

+0

나는 당신의 제안이 맞다는 것을 확신하지만, 여전히 일하기가 부족하다는 것을 알고 있습니다 - 편집을보십시오. – Mick

관련 문제