2010. 4. 22. 10:50

SurfaceView





기존에 제공되는 뷰를 이용하지 않고 custom한 ui를 만드는 방법은 여러가지인데

대부분의 case에서는 View를 상속받은 class를 하나 생성하고 onDraw method를 overriding하고

onDraw에 parameter로 넘어오는 canvas를 이용하여 그리면 된다.

좀더 뻘짓을 하기 위해서 이방법을 이용하지 않고 lcd화면과 직접 match가 되는 surface라는 걸 이용하는 방법이다. 이넘은 제공되는 함수도 몇개 더 되며, 물론 이 뷰에 다른 뷰를 박아도 알아서 잘 동작한다.

그리고 opengl es로 화면 출력할려면 이걸 써야된다는듯? (안해봐서 모름 ㅋㅋ)

package com.windweaver;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class Title extends SurfaceView implements Callback {  // 이쉑을 상속받고 저쉑을 구현
 Drawable mBlack;
 Drawable mRed;

 static int mSurfaceWidth;
 static int mSurfaceHeight;
 
 Canvas mCanvas;

 SurfaceHolder mHolder = getHolder();  // sufaceview에서 화면을 그릴려면 holder라는넘을 가지고 함
 
 public Title(Context context, AttributeSet attr) {
  super(context);
  
  mBlack = context.getResources().getDrawable(R.drawable.chip_black);
  mRed = context.getResources().getDrawable(R.drawable.chip_red);
    
  mHolder.addCallback(this);    // 콜백을 등록하면 surface와 관련된 함수들이 적절하게 호출됨
}

 @Override
 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // 필수함수1

 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) { // 필수함수2 : surface가 생성될때 호출됨
  mSurfaceWidth = this.getWidth();
  mSurfaceHeight = this.getHeight();
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) { // 필수함수3

 }

 @Override
 public void draw(Canvas canvas) { // 필수함수4 : 이넘은 platform에서 draw호출했을 경우에
                                                             // 자동으로 호출되는넘이니 여기서 필요한거 그려주면 됨
  super.draw(canvas);

  // black
  int blackX = logoX-mBlack.getIntrinsicWidth()-10;
  int blackY = (mSurfaceHeight - mBlack.getIntrinsicHeight())/2;
  mBlack.setBounds(blackX, blackY, blackX+mBlack.getIntrinsicWidth(), blackY+mBlack.getIntrinsicHeight());
  mBlack.draw(canvas);
  
  // red
  int redX = logoX+mLogo.getIntrinsicWidth()+10;
  mRed.setBounds(redX, blackY, redX+mRed.getIntrinsicWidth(), blackY+mRed.getIntrinsicHeight());
  mRed.draw(canvas);
  
 } 
}

* 사용자가 임의로 표면에 그릴때 사용하는 방법
    try {
     mCanvas = mHolder.lockCanvas(); // lock을 하면 canvas를 돌려줌
     mParent.draw(mCanvas);              // 받은 canvas로 그리고 싶은걸 그림
    } catch (InterruptedException e) {
     e.printStackTrace();
    } finally {
     if (mCanvas != null) {
      mHolder.unlockCanvasAndPost(mCanvas); // canvas를 사용했으면 돌려준다.
     }
   }