펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO
SurfaceView는 View를 상속받은 클래스로 Video Memory로 바로 접근하기 때문에 일반 View에서의 랜더링
속도보다 빠르다.
일반 View는 많은 그리기 작업을 하면 메인 스레드의 자원을 다 잡아먹어버리기때문에 상당히 느려지게 되는데
이러한 단점을 보완하기 위한 클래스라고 보면 된다
우선 액티비티에 SurfaceHolder.Callback을 해 주고, add unimplemented methods를 해 준다.
public class DrawClass implements SurfaceHolder.Callback{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
그럼 셋팅은 끝. 사용되는건 surfaceCreated와 surfaceDestoryed 정도가 되겠다.
surfaceCreated는 처음 서피스뷰가 생성될 때 호출되는데, 주의할점은 백그라운드 상태로 내려갔다가, 다시 올라오게 되면
surfaceview가 다시 created된다는점이다. created에서 thread를 실행시키는 작업을 할 경우
반드시 스레드가 동작중인지 여부를 먼저 확인해야한다. 그렇지않으면 익셉션 발생
surfaceChanged는 업데이트를 대비해 만들었다, 뭐라뭐라 하던데 잘 모르겠다. 사용하지않는듯하다.
이제 SurfaceView 구성은 하였고, 실시간으로 그리기를 실행하려면 Thread를 구동해야한다.
private Class PaintThread extends Thread {
public void run() {
while(!this.isInterrupted()){ //스레드가 인터럽트 될 때까지 반복 실행.
if (그리기 실행조건) {
//그리기 실행
doDraw();
}
}
}
}
나는 주로 드로우 관련부를 따로 만들어서 호출하는방식으로 사용한다.
비트맵을 그려보겠다. surfaceCreated에 다음과 같이 선언한다. (그 위에 Bitmap img, tempBitmap 전역변수로 선언해둔다)
팁 하나, 비트맵 이미지가 큰 경우 메모리를 상당히 많이 잡아먹어 종종 익셉션이 발생하게 되는데,
BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 1;
option.inPurgeable = true;
option.inDither = true;
이렇게 해 주면 비트맵이 먹는 메모리를 줄일 수 있다. 리사이클만으로는 감당이 안되는 경우가 생겨 찾다보니 이렇게 해주니 해결되더라. 이렇게 했을경우 단점은 잘 모르겠다. 고퀄리티를 요하는 작업이 아니었기때문에..
그리고
tempBitmap = BitmapFactory.decodeResource(res, R.drawable.img30x30, option);
img = Bitmap.createScaledBitmap(tempBitmap, imgWidth, imgHeight, true);
private void doDraw() {
try {
canvas = mHolder.lockCanvas(); //그리기 준비
int size = MainActivity.ARR_X.size();
canvas.drawColor(Color.GRAY); //배경색 설정
Paint p = new Paint();
p.setAntiAlias(true);
canvas.drawBitmap(img, imgX, imgY, p); //이미지를 X,Y위치에 그리기
}
catch (Exception e) {
}
finally {
mHolder.unlockCanvasAndPost(canvas); //그리기 종료
}
}
그리고 MainActivity의 xml에서
<패키지명.DrawClass
android:layout_width="500px"
android:layout_height="500px" />
와 같은식으로 호출한다.
여기까지가 SurfaceView 사용 방법이다.
참고로 위의 소스는 새로운 클래스를 만들어서 기존 액티비티에 영역추가하는식으로 사용한것이고
뷰와 마찬가지로 액티비티에서 바로 setContentView하여 적용 할 수도 있다.
문의점은 댓글 남겨주기바람
'Android > View' 카테고리의 다른 글
WebView를 이용해 javascript와 통신하기 (1) | 2014.04.09 |
---|---|
나인패치 (9patch) 이미지 만드는 방법 (1) | 2014.04.03 |
레이아웃의 종류와 사용법 (3) | 2014.02.04 |
터치이벤트(TouchEvent)로 비트맵이미지 이동시키기 2 (0) | 2013.12.24 |
터치이벤트(TouchEvent)로 비트맵이미지 이동시키기 (0) | 2013.12.24 |