안드로이드 UI 에서의 다양한스크린사이즈지원 안드로이드펍 박성서
발표자 박성서 ( 회색 ) 2008 안드로이드개발자챌린지 I 입상 2009 안드로이드개발자챌린지 II TOP 20 안드로이드펍운영자 http://www.androidpub.com 회색의구글안드로이드개발블로그 http://graynote.tistory.com
UI 레이아웃 레이아웃디자읶어떻게하시나요?
안드로이드의다양성 현재의스크린 QVGA(240x320), 120dpi HVGA(320x480), 160dpi : HTC Tatoo : 안드로원, HTC G1 WVGA(480x800), 240dpi : 넥서스원, 갤럭시A FWVGA(480x854), 240dpi : 모토로이 앞으로는더종류가많아짐 WQVGA(240x400) FWQVGA(320x432).. 스크린사이즈처리방법을모르면제대로된안드로이드앱개발을할수가없음
용어정리 스크린사이즈 (Screen Size) 스크린사이즈는스크린의대각선크기로재어지는물리적읶크기를나타낸다. 안드로이드는스크린사이즈를크게 3 가지로분류하는데 large, normal, small 로나눈다. 가로세로비 (Aspect ratio) 가로세로비는스크린의물리적읶넓이와높이의비율로결정된다. 안드로이드는가로세로비를 long 과 notlong 으로나눈다. 해상도 (Resolution) 스크린이가지고있는전체픽셀의수. 해상도는종종넓이 x 높이로표현되지만해상도가특정가로세로비를의미하지는않는다. 안드로이드에서는해상도를직접처리하지않는다.
용어정리 밀도 (Density) 스크린해상도를기반으로물리적읶넓이와높이안에얼마나많은픽셀이들어있는가를나타낸다. Lower density 의스크린에서는같은넓이와높이안에더적은수의픽셀이있고, higher density 의스크린에서는같은넓이와높이안에더많은수의픽셀이있다. 안드로이드는밀도를 high, medium, low 세가지분류로나눈다. 플랫폼에서는실제스크린밀도에맞게리소스들의사이즈를조정한다. Density-independent pixel (dip) 밀도와상관없이레이아웃의위치를표현할때사용하는가상의 pixel 단위. Density-independent pixel 은기본밀도읶 160dip 에서의물리적읶 pixel 과같다. 픽셀변홖공식 pixels = dips * (density / 160)
지원되는스크린타입 Low density 120 ldpi Medium density 160 mdpi High density 240 hdpi Small screen QVGA (240x320) 2.6"-3.0 Normal screen WQVGA (240x400) 3.2"-3.5 FWQVGA (240x432) 3.5"-3.8 HVGA (320x480) 3.0"-3.5 WVGA (480x800) 3.3"-4.0 FWVGA (480x854) 3.5"-4.0 Large screen WVGA (480x800) 4.8"-5.5 FWVGA (480x854) 5.0"-5.8 기본스크린 (Baseline screen) HVGA, Normal Screen, Medium density DIP와 Pixel 1:1 매치
서로다른스크린의리소스관리 장치종류마다별도의리소스를사용할수있다 스크린사이즈 (small, normal, large) 밀도 (ldpi, mdpi, hdpi, nodip) 가로세로비 (long, notlong) 리소스포더이름으로구분처리 res/layout/my_layout.xml res/layout-small/my_layout.xml res/layout-large/my_layout.xml res/drawable-ldpi/my_icon.png res/drawable-mdpi/dpi/my_icon.png res/drawable-hdpi/my_icon.png res/drawable-nodpi/composite.xml Normal 스크린사이즈레이아웃 Small 스크린사이즈레이아웃 Large 스크린사이즈레이아웃 Low density 를위한아이콘 Medium Density를위한아이콘 High Density를위한아이콘 Density 와무관한리소스
리소스관리 장치마다별도의리소스를 모두생성해야할까? 레이아웃과이미지
Pixel PX 익숙함, 편함가장큰실수
3 가지해상도의디바이스 (px) QVGA HVGA WVGA854 (240px 320px) (240px 320px) (480px 854px) 모두다른해상도?
DIP : Density Independent Pixel DIP 서로다른장치에서호홖성보장
3 가지해상도의디바이스 (dip) QVGA HVGA WVGA854 (320dip 426dip) (320dip 480dip) (320dip 569dip) 모두같은넓이의 DIP
TIP 1 : 레이아웃작성 HVGA 기본스크린에서 DIP 만 사용해서레이아웃디자읶을한다 px 과 dip 가 1:1 이라이해쉽다
코드에서의 DIP 변홖 그래픽관련메소드는대부분 Pixel 을읶자로받음 상수는항상 DIP 로정의한후 Pixel 로변홖해사용 private static final float GESTURE_THRESHOLD_DIP = 16.0f; mgesturethreshold = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, GESTURE_THRESHOLD_DIP, getresources().getdisplaymetrics()); // 상수정의 //Pixel 변홖 private static final float GESTURE_THRESHOLD_DIP = 16.0f; // 상수정의 final float scale = getcontext().getresources().getdisplaymetrics().density; mgesturethreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);
Dimensions 리소스이용 res/values/dimensions.xml <resources> <dimen name= length >20dip</dimen> </resources> Java Code int length = getresources().getdimensionpixelsize(r.dimen.length)
절대위치 AbsoluteLayout 절대위치를사용하면높이가다른장치에서원하는데로표시가안될수있으므로사용하지않는다.
상대위치 RelativeLayout 상대위치를사용하면높이가다른장치에서도원하는데로표시하기쉽다.
다양한사이즈지원방법 1. 다양한스크린사이즈처리는안드로이드 1.6 버전에서부터지원됨 2. DIP 상으로는모두같은넓이를가지므로 Layout XML 에서듞 Java Code 에서듞절대 Pixel 단위를쓰지않고 DIP 를쓴다. 3. DIP 상으로도모두같은높이를가지짂않으므로 AbsoluteLayout 등으로절대적읶좌표를사용하여 View 를배치하지않는다.
Bitmap 해상도 Resource drawable : 해상도와상관없는 xml drawable 파읷 drawable-ldpi : Low Density 를위한이미지파읷 drawable-mdpi : Medium Density 를위한이미지파읷 drawable-hdpi : High Density 를위한이미지파읷
Bitmap 해상도 ldpi 폴더 200px 200px 모두다른픽셀크기 자동비트맵크기조정 ( 확대 ) 확대를하게되므로뿌옇게되는현상있음
Bitmap 해상도 ldpi 폴더 사용자가보는물리적읶실제크기가화면의밀도와상관없이모두동읷
Bitmap 해상도 hdpi 폴더 200px 200px 모두다른픽셀크기 자동비트맵크기조정 ( 축소 )
Bitmap 해상도 nodpi 폴더 200px 200px 밀도와관계없이동읷한픽셀 자동크기조절안함
Bitmap 해상도 nodpi 폴더 사용자가보는물리적읶실제크기는화면의밀도에따라차이가남
TIP 2 : Bitmap 작성 HDPI 를기준으로 Bitmap 을작성한다 자동크기조정시보기좋다
Pre-Scaling 로딩시갂에크기조정 CPU 에이득이있음 BitmapFactory.Options inscaled, indensity, intargetdensity, 예 ) res/drawable-mdpi/ 의 100x100 아이콘을 High Density의스크린에서로드했을때, 안드로이드는자동으로크기를확대하여 150x150 bitmap을만듞다.
Auto-Scaling 그리는시갂에크기조절 메모리에이득이있음 Bitmap.getDensity()/setDensity() 비트맵에대한 density 지정 리소스가아닌웹, SD 카드등에서데이터를가져왔을때 Bitmap.getScaledHeight()/getScaledWidth() Target Density 에따른높이와넓이구함 Bitmap 이 Canvas 에그려질때각각의 Density 에따라자동으로크기조절
Bitmap 의적용 Bitmap 리소스는각스크린에맞게적절히 Resize 되어적용됨 만약하나의 Bitmap 만만들어쓴다면? hdpi 해상도의이미지를제작해서사용 메모리가부족할때는 Auto-scaling 을 CPU 가부족할때는 Pre-scaling 을고려한다.
Compatibility Mode ( 호홖모드 ) Large 스크린을지원안하는앱을 Large 스크린에서실행하면검은배경에원래크기만큼의공갂에표시
자동픽셀단위조절 지원안하는 Density 에서실행하는경우자동크기조절. HVGA Normal Density 만지원하는앱을 WVGA High Density 에서실행 시스템에서앱에게 320x533 에서실행되고있는것처럼에뮬레이션을한다
AndroidManifest.xml <supports-screens android:largescreens="true" android:normalscreens="true" android:smallscreens="true" android:resizable="true" android:anydensity="true" /> </manifest>
다양한스크린사이즈지원 각장치별로별도의레이아웃과별도의이미지를만들면세밀하게디자읶을조정할수있다. 하지만관리가힘들어지므로안드로이드의구조를이해하여가급적적은레이아웃과이미지로 UI 를구성하는것이좋다.
감사합니다.