안드로이드 개발환경을 구성하고 익숙하지도 않은 이클립스를 사용하여 Hello World 프로그램을 만들 때 가장 눈에 거슬리는 것이 다음 화면 이었다. 에뮬에서 사용할 가상머신의 규격을 설정하는 것인데 스마트폰 기기에 대해서 아는바가 없어 그냥 막고 품어 왔지만 중요한 부분이라서 정리해 본다.
스마트폰 스팩에 대해서 잘 정리해 놓은 자료가 있어서 퍼왔다. 스마트폰 별로 화면의 크기가 몇 인치이며 가로세로 비율 지원하는 해상도와 해상도에 대한 약어를 표시하고 있다.
V:H-ml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />-ml:namespace prefix = o />-ml:namespace prefix = o />-ml:namespace prefix = o /> |
픽셀 |
종류 |
크기 |
비 고 |
5:3 |
800*480 |
WVGA |
4.3” |
HTC HD2, HTC EVD 4G |
4.0 |
갤럭시S AMOLED |
3.7” |
HTC Desire
SAMSUNG 옴니아2 AMOLED Omnia-II |
3.5” |
옵티머스 Q |
3.0” |
갤럭시A AMOLED PLUS |
- |
SonyEricsson Xperia X1 |
80:49 |
800*490 |
- |
3.7” |
PANTECH 시리우스(Sirius) AMOLED |
- |
854*480 |
- |
3.7” |
Motorola MOTOROI |
4.0” |
SonyEricsson Xperia X10 |
4:3 |
640*480 |
VGA |
- |
HTC Touch Diamond |
320*240 |
QVGA |
- |
HTC Touch Dual |
1024*768 |
XGA |
9.7” |
APPLE 아이패드 |
16:9 |
640*360 |
- |
3.2” |
NOKIA 5800 Express Music |
3:2 |
480*320 |
HVGA |
3.0” |
안드로원 |
3.5” |
Apple iPhone 3GS (애플 아이폰 3GS)
APPLE 아이팟터치 |
- |
LG Andro-1 |
- |
HTC G1 |
960*640 |
|
3.5” |
APPLE 아이폰4G |
- |
1024*600 |
|
|
갤럭시 탭 |
스크린사이즈 (Screen Size) : 스크린 사이즈는 스크린의 대각선 크기 값으로 물리적인 크기를 나타낸다. 안드로이드는 스크린 사이즈를 large, normal, small 로 나눈다.
가로세로비 (Aspect ratio) : 가로 세로비는 스크린의 물리적인 넓이와 높이 비율을 말한다. 안드로이드에서는 리소스 제한자인 long, notlong 을 이용하여 화면 비율에 대한 layout 리소스를 제공한다 .
해상도 (Resolution) : 스크린이 가지고 있는 전체 픽셀수를 나타낸다 . 해상도가 보통 "넓이 * 높이" 로 표현되기는 하지만 해상도가 특정 가로세로비 (Aspect ratio) 를 의미하지는 않습니다 . 안드로이드에서는 해상도를 직접 처리하지는 않습니다 .
밀도 (Density) : 스크린 해상도를 기반으로 물리적 넓이와 높이안에 얼마나 많은 픽셀이 들어 있는가를 나타낸다. 저밀도(Lower density) 스크린에서는 같은 넓이와 높이안에 더 적은 수의 픽셀이 있고 고밀도(Higher Density) 스크린에서는 같은 넓이와 높이안에 더 많은 수의 픽셀이 있다. 안드로이드에서 Density는 아주 중요한 개념이다. 만일 UI 요소들을 pixel 단위로 크기를 지정하면 낮은 density 화면에서는 더 크게 보이고 높은 density 화면에서는 더 작게 보인다. Android는 density를 high, medium, low로 나누며 , 플랫폼에서는 실제 스크린밀도에 맞게 리소스들의 사이즈를 조정한다. 밀도는 (dpi : dot per inch, density per inch, ppi : pixel per inch) 단위를 사용한다.
길이단위 : View나 위젯들에게 부여된는 _width, _height 속성값에 부여되는 단위로 px(픽셀), in(인치), mm(밀리미터), pt(포인트) 처럼 기존의 웹개발에서 많이 봐왔던 단위도 있지만 dp(또는 dip), sp(또는 sip, 밀도에 독립적니 폰트단위) 같은 생소한 단위도 있다. dip(Density Independent Pixel)는 밀도(density)와 상관없이 레이아웃의 위치나 크기를 표현할 때 사용하는 가상의 pixel 단위다. 1dip는 밀도가 160 일때 1픽셀에 해당한다. 즉 Mediaum Density(160), mdpi 화면에서는 1pixel = 1dip 이며 , 다른 dip에서 픽셀변환공식은 pixels = dips * (density / 160) 로 처리된다.
표준 디스플레이 해상도 : VGA, QVGA 같은 약어들을 알아보자. 640*480 해상도를 VGA(Video Graphic Array) 라고 부르며 여기에 Quarter, Half, Wide, Full, Super, Ultra 같은 걸 붙여서 크기를 나타낸다.
QVGA(Quarter VGA) 320*240 = 0.077mpx
WQVGA(Wide QVGA) 400*240
FWQVGA(Full WQVGA) 432*240
HVGA(Half VGA) 320*480 = 0.15mpx 2:3
VGA(Video Graphic Array) 640*480=0.3mpx 4:3
WVGA(Wide VGA) 800*480 5:3
FWVGA(Full Wide VGA) 854*480 16:9
SVGA(Super VGA) 800*600 = 0.5mpx 4:3
XGA/XVGA(Extended Graphic Array) 1024*768 = 0.8mpx
WXGA 1280*800 = 1.0mpx
SXGA 1280*1024 = 1.3mpic
WXGA+ 1440*900 = 1.3mpx
SXGA+ 1400*1050 = 1.4mpx
WSXGA+ 1680*1050 = 1.7mpx
UXGA 1600*1200 = 1.9mpx
WUXGA 1920*1200 = 2.3mpx
QXGA 2048*1536 = 3.1mpx
WQXGA 2560*1600 = 4.1mpx
QSXGA 2560*2048 = 5.2mpx
WQSXGA 3200*2048 = 6.6mpx
QUXGA 3200*2400 = 7.7mpx
WQUXGA 3840*2400 = 9.2mpx
WUQSXGA 4200*2690 = 11.3mpx
이정도 정리하고 나니까 에뮬레이터의 시작할 때 올라오는 시작옵션창이 어느정도 이해가 간다.
이제 한 단계 넘어서 다양한 화면크기의 다양한 밀도를 가지는 안드로이드 모바일 기기를 고려하면서 개발하기에 필요한 정보들을 정리해 본다. 다음 표는 Android 에서 지원되는 Screen Size 와 Density 간의 관계를 나타낸다.
안드로이드는 폰이 다양해서 여러 UI를 동시 처리하기 위해서 신경써야 한다. 그중 제일 중요한 것은 density 이며 dpi라는 단위를 사용해야 유연성이 높일 수 있다. 이 표는 가지각색의 안드로이드 기기을 일정정도 그룹화하여 이미지나 레이아웃을 구성하는 기준으로 삼자는 것이다. Baseline은 HVGA, Normal Screen, Medium density 이며 dip와 pixel이 1:1 로 매칭되는 조건이다. 국내 폰들은 현재 WVGA(400*800) hdpi 가 지배적이다. 실제 개발 시 장치 종류마다 별도의 리소스를 따로 마련해 두고 각각의 폴더이름에 밀도를 나타내는 (ldpi, mdpi, hdpi, nodip) 같은 한정자를 사용하여 관리한다. 다양한 크기 및 density 를 지원해야 하기 때문에 안드로이드 UI 개발은 iPhone UI 개발보다 훨씬 복잡하고 귀챦다. 그렇기 때문에 안드로이드가 내부적으로 UI를 처리하는 방식을 이해하고 개발할 앱의 타겟을 잘 잡아서 만들어야 한다 .
표준 리소스를 디렉토리 샘플
res/anim
res/raw
res/xml
res/layout/*.xml -> Noraml 스크린 사이즈 레이아웃
res/layout-small/layout.xml -> Small 스크린 사이즈 레이아웃
res/layout-large/layout.xml -> Large 스크린 사이즈 레이아웃
res/drawable
res/drawable-ldpi/icon.png -> Low density 를 위한 아이콘
res/drawable-mdpi/icon.png -> Medium density 를 위한 아이콘
res/drawable-hdpi/icon.png -> High density 를 위한 아이콘
res/drawable-nodpi/res.xml -> density 와 무관한 리소스
res/menu
res/values/strings.xml, colors.xml, styles.xml, arrays.xml, dimens.xml
res/values-ko
접미어
언어 (us, kr, fr, ja), 지역 (rUS, rKR, rFE), 화면방향 (port, land, square), 해상도 (92dpi, 108dpi),
가로세로비 (long, notlong), 스크린사이즈 (small, normal, large, 320*240, 480*320)
코드나 리소스에서 참조시 접미어는 붙이지 않는다. 여러개의 접미어를 사용할 때 - 를 연속해서 사용하고 일정 순서에 의거하여 작성해야 한다. 대소문자를 구분하고 중첩은 허용하지 않는다.
How Android Supports Multiple Screens
(원문펌 http://overoid.tistory.com/9)
안드로이드에서는 런타임시에 아래 3 가지 방식 중 하나로 다양한 화면을 지원합니다 . 아주 중요한 내용입니다 .
i) Pre -Scaling ( 보통 bitmap 이미지 처리시에)
Pre -Scaling 은 로딩시점에 크기를 조절합니다 . CPU 에 이득이 있다고 알려져 있습니다. Pre -Scaling 은 폰의 Density 를 기준으로 동일한 dpi 디렉토리에 지정된 리소스를 로딩하며 이때는아무런 크기 변환없이 보여줍니다 . 즉 폰이 hdpi density 라면 res/drawable-hdpi 디랙토리 하위의 리소스를 먼저 찾아서 있다면 아무런 크기 변환없이 그대로 보여주게 됩니다. 만일 매칭되는 리소스가 없다면 디폴트 리소스 (basline) 를 로딩하고 로딩 시에 적합한 density로 크기 변환을 합니다 . 예를들어 res/drawable-mdpi/ 에 100*100 아이콘만 존재한다고 할 때 만일 폰의 사양이 hdpi 라면 안드로이드는 drawable-mdpi 하위의 아이콘을 읽을때 자동으로 크기를 확대해서 150 * 150 bitmap 을 만듭니다. 반대로 drawable-hdpi/ 에 150*150 아이콘만 존재할 때 mdpi 폰에서 읽으면 자동으로 100*100 아이콘으로 크기를 변환합니다 . drawable-hdpi 및 drawable- mdpi에 모두 이미지가 존재한다면 별도의 스케일 변환 작업이 필요없으니 좀 더 성능에 유리 합니다.
ii) Auto-scaling (pixel dimensions and coordinates)
Auto-scaling 은 그리는 시점에 크기를 조절합니다 . 메모리에 이득이 있다고 알려져 있습니다 . 주로 Pixel 좌표, Pixel Dimesion 값, Application 에서 사용된 Pixel 수식 등에 적용되며, 리소스가 아닌 웹이나 SD카드에서 Bitmap 데이터를 가져왔을 때도 적용됩니다. 쉽게 얘기하면 App에서 ( 10,10) 에서 (100,100) 좌표로 4각형을 그리도록 구현했다면 High -Density(240dpi) 화면을 가진 Device 에서는 그리는 시점에 자동으로 스케일을 변환해서 (15,15) (150,150) 좌표에 사각형을 그리게 된다 .
ii) Compatibility Mode (호환모드)
Large 스크린을 지원 안하는 앱을 Large 스크린에서 실행하면 검은 배경에 원래 크기만큼만 표시합니다. 보기에는 별로입니다 . 앱이 싼티 납니다. 아 .. 여전히 복잡하고 어렵군요 . 원문 보시면 좀 더 상세하지만 복잡한 내용들로 가득 차 있습니다. 중요한 점은 안드로이드가 여러 화면사이즈를 지원하기 위해서 런타임시에 자동으로 크기를 바꾼다는 것을 기억하십시요 .
제가 사용하는 기본 레이아웃 디자인 룰은 다음과 같습니다 .
i) 레이아웃 디자인시에는 HVGA 기본 스크린 사이즈를 중심으로 DIP 단위만을 사용해서 디자인합니다. px과 dip가 1:1 이라서 화면 크기에 대응하여 사이즈 결정하기가 좋습니다. 320 * 480 화면 기준으로 들어갈 이미지나 UI 요소들 각각의 가로 사이즈를 px로 계산한 후 코딩시에는 그 값의 단위를 dip 로만 입력하 면 됩니다 .
ii) AbsoluteLayout 을 사용하지 않습니다. 즉 , 화면의 절대 좌표 보다는 상대 좌표를 사용해야 합니다. 이거 사용해서 디자인하면 ..나중에 감당 안됩니다 .
iii) Bitmap 은 HDPI 기준으로 만듭니다. 그래야 자동으로 크기가 조정 되더라도 보기에 좋습니다. 즉 HVGA 를 기준으로 계산했을 때 100 * 100 이미지가 필요하다면 HDPI 기준으로 크기의 1.5 배인 150 *150 크기로 실 이미지를 제작하시면 됩니다. 만일 여력이 된다면 hdpi 및 mdpi 기준으로 각각 만드는 것도 나쁘지는 않습니다. 위에서 언급했듯이 성능에 유리합니다.
iv) 각 장치별로 레이아웃 및 이미지를 모두 별도로 만들어서 세밀하게 조정할 수도 있지만 그런 경우 관리가 힘듭니다 . 가급적 레이아웃과 이미지를 적게 사용해서 통일된 UI를 구성하는 것이 좋습니다.
스마트폰 해상도관련 사항
2.1 가로/세로 값
this.getWindowManager().getDefaultDisplay().getWidth();
this.getWindowManager().getDefaultDisplay().getHeight();
context.getResources().getDisplayMetrics().widthPixels
context.getResources().getDisplayMetrics().heightPixels
context.getResources().getDisplayMetrics.density
2.2 주의 사항
i) 3요소가 일치해야 한다
<uses-sdk android:minSdkVersion="8" />... .
프로젝트 만들때 Build target설정에서 Platform 2.2버젼...
스마트폰의 안드로이드 OS 버젼(2.2)...
ii) 스마트폰이나 에뮬의 버젼이 제일 최신버젼이어야 한다
스마트폰의 안드로이드 OS 버젼을 최대기준으로 볼 때 uses-sdk와 Build target이 적거나 같아야 한다.
iii) 결론
일반적으로 대부분의 스마트폰 해상도는 480*800아나 위의 두 가지 조건이 맞지 않으면 320*533으로 나올 것이다. 예를 들어 스마트폰은 2.2버젼인데 새로나온 2.3버젼인 9API로 프로젝트를 만들면 해상도는 320*533으로 나올 것이다.
2.3 해상도 테스트
i) AndroidManifet 상에
<supports-screens android:largeScreens = ”true” android:normalScreens = ”true”
android:smallScreens = ”true” android:anyDensity = ”true”/>
ii) 글자의 크기는 XML상에 px가 아닌 sp로 할 것.
iii) Widget의 크기 및 padding은 dip로 사용할 것.
iv) Layout은 LinearLayout 이나 RelativeLayout 등을 사용할 것
v) 안드로이드 에뮬레이트 안의 AVD manager를 Add해서 해상도를 여러 개 적용하여 테스트하면
도움이 될 것임.
해상도 밀도 관련 : (구글크롬으로 접속해서 번역하면 쉽게 이해 볼수 있당)
참고 http://www.kandroid.org/guide/practices/screens_support.html
스마트폰 해상도 정리
참고 : http://blog.naver.com/handyson/120391295