Android/정리2010. 5. 19. 18:00

Graphics

Android 그래픽은 2D graphic library OpenGL 이용한 3D그래픽이 준비되어 있다. 2D graphic drawable package 공통으로 사용되는 API들이 정의되어 있으며, 3D graphic Khronos OpenGL ES package Android OpenGL utility들로 구성되어 있다.

Android graphics are powered by a custom 2D graphics library and OpenGL ES 1.0 for high performance 3D graphics. The most common 2D graphics APIs can be found in the drawable package. OpenGL APIs are available from the Khronos OpenGL ES package, plus some Android OpenGL utilities.

Canvas 사용하는 방법은 View 구조에서 어떻게 그려야 하는지에 대해 좋은 정보를 제공할것이다.

 

Consider your Options

2D 그래픽 그리기

1.     Layout View 객체에 graphic이나 animation 그린다. 그리기 작업은 시스템의 일반적인 View구조의 그리기 순서에 따라 그려지게 된다. 간단하게 View내부에 graphic 정의한다.

2.     Canvas 직접 그린다. 해당 클래스의 draw() 호출하거나 Canvas draw…() 호출하여 그림

 

1 View 그리기는  가장 편하고 좋은 선택이다. Simple Graphics Inside a View. <- 참조

2 Canvas 그리기는 정기적으로 다시 그리기가 필요한 경우에 좋은 선택이다. Video game들은 Canvas 그리기 방법을 사용한다.

·         UI Activity 동일한 스레드상에서 layout custom View component 생성되어 있는 경우 invalidate() 호출하면 onDraw()콜백이 동작한다.

·         또는 별도의 스레드의 경우 동일스레드에서 처리하는 만큼 Canvas 그리기를 수행하고 SurfaceView 다루는 것이 빠르다. ...Begin by reading Draw with a Canvas.

Simple Graphics Inside a View

단순한 그래픽(이미지, 모양, 색상, 미리만들어진 애니매이션등..) 그리고자 한다면 View 백그라운드를 그리고 layout안에 ImageView content영역에 그리기만 하면 된다. 그렇다면 문서를 건너뛰고 어떻게 그래픽과 애니매이션을 그리는지 배우길 바란다(2D Graphics 참조)

Draw with a Canvas

별도의 그리기를 구현하고자 한다면 Canvas 이용해서 그려야 한다.

onDraw()콜백메소드에 Canvas객체가 제공되며 이를 이용하여 그릴수 있다. SurfaceHolder.lockCanvas 통해 canvas 얻을수도 있으며 이는 SurfaceView객체로 다룰 가능하다.

Canvas 별도로 새로 생성하고자 할때는 반드시 실제로 그려지게될 Bitmap 정의해야 한다. Bitmap Canvas 항상 필요한 존재이다. 아래와 같이 새로운 Canvas 셋업할수 있다.

Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);

이렇게 생성된 canvas Canvas.drawBitmap(Bitmap, …)메소드중 하나를 이용하여 다른 canvas 복사할 있다. View.onDraw() SurfaceHolder.lockCanvas() 통해 얻어진 Canvas 통해서 그리는 것을 권장한다.

drawBitmap(…), drawRect(…), drawText(…) 많은 함수 지원. 다른 클래스들도 draw()메소드를 지원한다. Drawable클래스 같은 경우 자신의 draw()메소드를 지원하여 Canvas 인자로 사용되어 그려질 있다.

On a View

어플리케이션이 프로세싱이 많거나 frame-rate속도를 요하지 않는 경우(chess game같은 느린 애니매이션을 처리하는 게임등), View.onDraw()에서 Canvas 그리는 customView 만들어 사용할 있다. 이렇게 하면 안드로이드 프레임워크에서 제공하는 Canvas 이용하여 쉽게 구현가능하다.

1.     View class extend한다.

2.     onDraw() callback 정의한다. -> 메소드는 프레임워크에 의해 뷰가 그려져야 호출될것이다. draw관련 처리를 하는 지점이며 Canvas객체가 넘겨져 와서 객체를 다루면 된다.

안드로이드 프레임워크는 필요할때만 onDraw() 호출한다. 그려져야 하는 싯점이 되면 애플리케이션에서는 invalidate() 호출함으써 다시 그려지게 있다.

View component onDraw()에서는 Canvas객체를 사용하여 drawing 처리한다. Canvas draw…() canvas 넘겨져온 클래스의 draw()메소드가 호출되어 drawing 완성된다. 완성이 되면 프레임워크는 시스템에 의해 처리되는 비트맵을 그리기 위해 canvas 사용할것이다.

Note:  main activity thread 아니라 다른 thread에서 다시그리기를 수행하려면 postInvalidate() 호출해야 한다.

View class 확장에 대한 안내는 Building Custom Components  참조하라.

For a sample application, see the Snake game, in the SDK samples folder: <your-sdk-directory>/samples/Snake/.

On a SurfaceView

SurfaceView View구조내에서 surface 그리는 목적으로 고안된 특별한 subclass이다. 목적은 애플리케이션의 두번째 스레드에서 별도로 그려서 시스템의 View구조에서 그리기 타임까지 기다리지 않도록 하게 하기 위해 고안되었다. 두번째 thread에서 참조하는 SurfaceView 자신만의 Canvas 그리기를 수행한다.

1.     SurfaceView extend 새로운 클래스를 선언한다.

2.     SurfaceHolder.callback implement한다. 콜백 subclass 하부의 Surface 대한 정보와 함께 통지하는데 생성, 변경 또는 제거되었을 통지하게 된다. 이벤트를 통해서 언제 그리기를 시작해야 하는지 알수 있고, 새로운 surface속성에 맞게 조정하고, 언제 그리기를 종료하고 테스트를 죽일지등을 알수 있다. SurfaceView에서 두번째 Thread 정의하여 모든 drawing procedure 수행하는 것이 좋다.

3.     SurfaceHolder 생성한다. Surface 객체를 직접 처리하지 않고 SurfaceHolder 통해서 하는 것이 좋다. SurfaceView 초기화되면 getHolder() SurfaceHolder 얻는다.

4.     addCallback() 호출하여 SurfaceHolder.Callback으로부터 이벤트를 수신하도록 한다. SurfaceHolder.Callback SurfaceView클래스내에서 override하여 addCallback()한다.

5.     두번째 thread에서 Surface Canvas draw하려면 반드시 SurfaceHandler 전달해야 하며 lockCanvas() canvas 얻어야 한다. 이렇게 해야 SurfaceHolder 제공해준 Canvas 얻게 된다.

6.     Canvas drawing 한번 수행하면 canvas object 인자로 unlockCanvasAndPost() 호출해야 한다. lockCanvad() unlockCanvasAndPost() draw 반드시 쌍으로 호출되어야 한다.

 

Note: 한번 canvas 얻어져서 사용되면 canvas 이전상태를 유지한다. 따라서 적절하게 animate 하려면 surface전체를 re-paint해야 한다. 경우 drawColor() drawBitmap()등으로 background 갱신하면 된다. 그렇게 하지 않으면 이전 이미지가 표시될 것이다.

 

For a sample application, see the Lunar Landar game, in the SDK samples folder: <your-sdk-directory>/samples/LunarLander/. Or, browse the source in the Sample Code section.

 

Posted by 삼스