그건 activity에서 SurfaceView 인스턴스와 ImageView 인스턴스를 생성해서 후자를 전자에 복사해주는것같은데요,
저는 SurfaceView의 구조와 사용법에대해 잘 이해가 안가서 도움을 얻고자 글을 또 올려봅니다.
모든 질문들은 SurfaceView를 상속받아 클래스를 만들어 사용한다고 보고 질문을 할게요.
질문 1.
구현해야할 함수가 생성자, created, changed, destroyed 4가지가 있는데요,
여기서 생성자에서 holder를 만들어서 addcallback을 해주는데 이것의 의미를 잘 모르겠네요..
callback이란 함수가 자동으로 create 와 destroy를 해준다는 개념정도만..이해가갑니다.~_~;
질문2.
이 클래스 안에서 ImageView 클래스의 인스턴스를 몇개 만들어서 여러개의 그림을 출력해 주려면
어떻게 holder를 지정해주고 addcallcack을 해야할지 잘 모르겠습니다.
또 surfaceCreated와 changed, destroyed의 함수에서 어떻게 처리해줘야 할지도..
구조의 이해를 돕기위해 간단한 예제라도 보여주시면 고맙겠습니다 ㅠ_ㅠ
제가 surfcaeView를 사용하려는 이유는
카메라화면을 바탕으로 받아온후 여러개의 이미지를 그위에 출력해준후, 각각의 이미지에 에니메이션을 적용해서
이미지가 움직이게 하려고 합니다..
제가 예제를보고 간단하게 그림하나 띄우는걸 해봤는데.. 잘안되네요 ~_~; 잘못된 부분좀 집어주시면 고맙겠습니다 ㅠ
public class GraphicsView extends SurfaceView implements SurfaceHolder.Callback {
public class ImgThread extends Thread {
private Drawable Img;
private SurfaceHolder ImgHolder;
private int ImgWidth;
private int ImgHeight;
public ImgThread(SurfaceHolder surfaceholder, Context context){
ImgHolder = surfaceholder;
Img = context.getResources().getDrawable(R.drawable.sample);
ImgWidth = Img.getIntrinsicWidth();
ImgHeight = Img.getIntrinsicHeight();
}
public void run(){
while(true){
Canvas c=null;
c = ImgHolder.lockCanvas();
dodraw(c);
}
}
public void dodraw(Canvas canvas){
Img.setBounds(50,50,100,150);
Img.draw(canvas);
}
}
////////Thread 클래스 끝/
private SurfaceHolder holder;
private ImgThread imgThread;
public GraphicsView(Context context){
super(context);
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
imgThread = new ImgThread(holder, context);
setFocusable(true);
}
public ImgThread getThread(){
return imgThread;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
imgThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
imgThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
public void run() {
while (true) {
Canvas c = null;
try {
c = ImgHolder.lockCanvas(null);
dodraw(c);
} finally {
if(c != null) ImgHolder.unlockCanvasAndPost(c);
}
}
}
흠.. 위와같이 unlock을 넣어봐도 똑같네요.. 아무래도 그럼 Activity를 잘못만든것 같은데..
이게 Activity코드입니다.. 틀린부분좀 찝어주시면 고맙겠습니다 ㅠㅠ
public class Test extends Activity {
private GraphicsView camView; // SurfaceView를 상속받아 만든 클래스
private ImgThread imgThread; //GraphicsView 클래스안에있는 이너쓰래드클래스
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
camView = new GraphicsView(this);
imgThread = camView.getThread();
setContentView(camView);
}
}
서피스뷰가 다음 보여줄거를 버퍼에 넣었다가 앞의 이미지가 보여진후 버퍼에 있는 다음 이미지를 보내는 거라고 본거 같은데,
카메라의 미리보기에 쓰인다는 SURFACE_TYPE_PUSH_BUFFERS는 버퍼를 소유하지 않는 서피스라면(API에 그렇게 써있는 거 같은.....)
버퍼에 넣었다가 보내려는 이미지와 버퍼없이 보내려는 미리보기가 그래서 꼬이는 걸까요?...
SURFACE_TYPE_NORMAL 로 바꾸고,
public void dodraw(Canvas canvas){
canvas.drawBitmap(카메라에서 오는 미리보기 이미지, 0, 0, null); // 요런거까지 같이 넣어서 계속 갱신해줘야 하는게 아닐까요
Img.setBounds(50,50,100,150);
Img.draw(canvas);
Img2.setBounds(100,50,250,150);
Img2.draw(canvas);
}