2010.08.17 15:16

[강좌A05] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part1




오늘의 안드로이드 실전 개발 강좌는 전 시간에 이어 저희가 개발할 앱의 레이아웃 및 리소스들을 만들어 보도록 하겠습니다

전체 강좌 목차
[강좌A01] Moteodev Studio를 이용한 안드로이드 개발 환경 구축 가이드
[강좌A02] 안드로이드 개발 참고 서적 소개
[강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe
[강좌A04] 안드로이드 실전 개발 - 아이콘 제작
[강좌A05] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part1

추천해 드린 책들 중 레이아웃 및 리소스 부분은 먼저 공부하셨는지 모르겠습니다. 최소한 그 부분은 먼저 공부하시고 제 강좌를 보시기 바랍니다. 대충 훑어 보시면 됩니다. 블로그에서 대부분의 안드로이드 책에 있는 내용까지 모두 다룰려면 거의 책을 써야 되는 상황이라 아주 초보적인 내용은 다루지 않기 때문에 책을 보신 후 블로그 포스트를 보시면 설명을 이해하는데 도움이 될 것입니다.

먼저 Motodev 실행하시고 (eclipse에 SDK 설치하신 분도 상관없습니다) Motodev > New > New Android Project 실행하시고, 아래 그림에 보이듯이 



프로젝트 정보를 설정후 생성합니다.

프로젝트 명은 “Hangul2English”

Target SDK : Android 2.0 (국내 출시용이므로 2.0 으로 해도 무방합니다. Google Market에 해외 사용자들도 포함해서 Release 하실려면 적어도 1.6으로 만드셔야 합니다. 아직 1.5 사용자도 많긴 하지만, 1.5와 1.6사이에 변경된 게 많아서.. 1.6정도로 타협하시면 될 것 같습니다.)

Package Name : com.overoid.hangul2english (제 블로그의 앞자리를 땄습니다.)

프로젝트를 생성하셨으면 아래 그림과 같이 패키지 및 디렉토리를 추가하여 구성합니다.

com.overoid.hangul2english.data – sqlite 관련된 소스가 들어갈 예정입니다.

com.overoid.hangul2english.util – utility class

 

화면이 많아서 소스가 복잡해지면 저는 activity / adapter / view 용 패키지를 따로 만들어서 사용하기도 합니다. 구글에서 만든 패키지들를 보면 아무리 복잡해도 별도의 패키지를 안 만들고 메인 폴더 하위에 수십개의 클래스 파일이 다 들어가 있습니다. 머리가 좋은 모양입니다. 저는 파일이 너무 많아지면 이게 그건지 저게 그건지 너무 헷갈립니다. 본 프로젝트는 워낙 화면이 간단한지라 나눌 필요는 없을 것 같습니다.

 

만일, 개발하시려는 앱이 많은 화면과 뷰를 가지고 있다면 아래와 같이 패키지를 나누셔도 좋을것 같습니다. (그냥 제 취향입니다.)

 

com.overoid.hangul2english.activity

com.overoid.hangul2english.activity.adapter

com.overoid.hangul2english.activity.view

 

res\ 하위에 drawable 디렉토리를 추가합니다. drawable 에는 xml로 된 리소스(이미지 등) 파일이 들어갈 예정입니다.

 

values-ko 디렉토리도 추가한 후 values/strings.xml 파일을 복사해서 붙여넣습니다. 한글 문자열을 저장할 파일입니다. values-ko 라고 디렉토리를 만들어서 사용하시면 android os가 폰 설정된 언어셋을 읽어서 언어에 맞게 strings.xml 파일을 로드해서 처리합니다.

 

기본 작업이 끝났습니다.

이제 처음으로 작업할 내용은 이미지나 버튼을 위한 리소스(이미지 등) 작업을 먼저 하겠습니다. 나중에 해도 상관없습니다. 제 개발 스타일입니다.

.

저희가 개발할 앱의 UI 기획서를 다시 보겠습니다.


이 화면 요소 중 1, 2, 3, 4, 5, 7 bitmap(png) 이미지 파일을 로드 한 것 입니다. 6번도 이미지이긴 하지만 xml로 정의해서 로딩시에 그린것입니다.

먼저 UI 구성에 필요한 이미지를 제작 혹은 구하셔서 res\drawable-hdpi 디렉토리에만 저장합니다. (아이콘 제작은 이전 포스트(http://overoid.tistory.com/7) 을 참고하세요)

여기서 잠깐..

안드로이드가 여러 크기의 화면을 어떻게 지원하는지 잠깐 돌아보겠습니다.

원문은 http://www.kandroid.org/guide/practices/screens_support.html 여기에 있습니다. 이 문서는 반드시 읽어 보시기 바랍니다. 아주 중요한 문서입니다. 그렇지 않으면 나중에 복잡한 UI를 여러 화면 사이즈에 대응해야 하는 앱을 만들 때 고생하십니다.

 

제가 소개해 드린 알짜만 골라 배우는 안드로이드 프로그래밍 2” 에도 원문 문서를 기반으로 상세히 관련 내용이 추가되어 있습니다. 오호.. 오늘 찾아보니 번역하신 분도 있군요. http://materer.tistory.com/archive/201005 이 문서입니다.

 

여기에서는 위 내용 중 꼭 필요한 일부분만 간략하게 설명하도록 하겠습니다.

먼저 용어 설명입니다.


스크린사이즈(Screen Size) : 스크린 사이즈는 스크린의 대각선 크기 값으로 물리적인 크기를 나타냅니다. 안드로이드는 스크린 사이즈를 large, normal, small 로 나눕니다.

가로세로비(Aspect ratio) : 가로세로비는 스크린의 물리적인 넓이와 높이 비율을 말합니다. 안드로이드에서는 리소스 제한자인 long, notlong을 이용하여 화면 비율에 대한 layout 리소스를 제공합니다.

해상도(Resolution) : 스크린이 가지고 있는 전체 픽셀수를 나타냅니다. 해상도가 보통 넓이 * 높이로 표현되기는 하지만 해상도가 특정 가로세로비(Aspect ratio)를 의미하지는 않습니다. 안드로이드에서는 해상도를 직접 처리하지는 않습니다.

밀도(density) : 스크린 해상도를 기반으로 물리적 넓이와 높이안에 얼마나 많은 픽셀이 들어있는가를 나타냅니다. Lower density의 스크린에서는 같은 넓이와 높이안에 더 적은 수의 픽셀이있고, Higher density의 스크린에서는 같은 넓이와 높이안에 더 많은 수의 픽셀이 있습니다.  안드로이드에서 density는 아주 중요한 개념입니다. 만일, UI 요소들을 pixel 단위로 크기를 지정하면 낮은 density 화면에서는 더 크게 보이고, 높은 density 화면에서는 더 작게 보입니다. Androiddensity high, medium, low 로 나누며, 플랫폼에서는 실제 스크린밀도에 맞게 리소스들의 사이즈를 조정합니다.

Density Independent Pixel(dip) : density와 상관없이 레이아웃의 위치를 표현할 때 사용하는 가상의 pixel 단위입니다.. Density-independent pixel default density 160dip 에서의 물리적 pixel과 같다. Mediaum Density(160), mdpi 화면에서는 1pixel = 1dip이며, 다른 dip에서 픽셀변환공식은 pixels = dips * (density / 160) 로 처리됩니다.



다음 표는 Android에서 지원되는 Screen Size Density 간의 관계를 나타낸 내용입니다.

   Low density (120), ldpi  Medium density (160), mdpi  High density (240), hdpi
 Small screen  QVGA (240x320),
 2.6"-3.0" diagonal
   
 Normal screen  

W QVGA (240x400),
  3.2"-3.5" diagonal

 

 FWQVGA (240x432),
 3.5"-3.8" diagonal
 HVGA (320x480),
3.0"-3.5" diagonal
 

  WVGA (480x800),
  3.3"-4.0" diagonal

 

FWVGA (480x854),
3.5"-4.0" diagonal
 Large screen    

  WVGA (480x800),
  4.8"-5.5" diagonal

 

 FWVGA (480x854), 
 5.0"-5.8" diagonal
 


이 표에서 BaselineHVGA, Normal Screen, Medium density 이며, dip pixel 1:1로 매칭되는 조건입니다. 대부분의 국내 폰들은 WVGA(400*800) hdpi 입니다.

 

실제 개발시 장치 종류마다 리소스 한정자를 사용하여 별도의 리소스를 지정할 수도 있습니다.
밀도(ldpi, mdpi, hdpi, nodip)

가로세로비(long, notlong)

스크린사이즈(small, normal, large)

 

리소스를 디렉토리명으로 구분한 샘플입니다.

Res/layout/layout1..xml -> Noraml 스크린 사이즈 레이아웃

Res/layout-small/layout1.xml -> Small 스크린 사이즈 레이아웃

Res/layout-large/layout1.xml -> Large 스크린 사이즈 레이아웃

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와 무관한 리소스

 

무슨 말들인지 어렵습니다. 하하~ 쉽다구요. 여러분들은 머리가 저보다 훨씬 좋으신 겁니다. 위에서 얘기한 것중 이것만 기억하십시요. 안드로이드는 폰이 다양해서 여러 UI를 동시 처리하기 위해서 신경써야 한다. 그중 제일 중요한 것은 density이며, dpi라는 단위를 사용해야 한다.

 

이처럼 다양한 크기 및 density를 지원해야 하기 때문에 안드로이드 UI 개발은 iPhone UI 개발보다 훨씬 복잡하고 귀챦습니다. 그렇기 때문에 안드로이드가 내부적으로 UI를 처리하는 방식을 이해하고, 개발할 앱의 타겟을 잘 잡아서 만들어야 합니다.


하지만 국내 TStore에 올라오는 어플들을 보면 국내 출시된 폰이 거의 큰 화면 위주라 이런거 신경안쓰고 큰 화면 기준으로 개발된 앱들도 더러 있는 것 같습니다. 어떻게 아냐구요? 다음 강좌에 나올 리소스 해킹편을 보시면 다른 앱들의 리소스를 들여다 보시면 이해가 되실 겁니다.

 

How Android Supports Multiple Screens

 

안드로이드에서는 런타임시에 아래 3가지 방식 중 하나로 다양한 화면을 지원합니다. 아주 중요한 내용입니다.

 

1.  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에 모두 이미지가 존재한다면 별도의 스케일 변환 작업이 필요없으니 좀 더 성능에 유리합니다.

 

2. 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) 좌표에 사각형을 그리게 된다.

 

3. Compatibility Mode(호환모드)


Large
스크린을 지원 안하는 앱을 Large 스크린에서 실행하면 검은 배경에 원래 크기만큼만 표시합니다. 보기에는 별로입니다. 앱이 싼티 납니다.


.. 여전히 복잡하고 어렵군요. 원문 보시면 좀 더 상세하지만 복잡한 내용들로 가득 차 있습니다.

중요한 점은 안드로이드가 여러 화면사이즈를 지원하기 위해서 런타임시에 자동으로 크기를 바꾼다는 것을 기억하십시요.

 

제가 사용하는 기본 레이아웃 디자인 룰은 다음과 같습니다.

 

1. 레이아웃 디자인시에는 HVGA 기본 스크린 사이즈를 중심으로 DIP 단위만을 사용해서 디자인합니다. (px dip 1:1 이라서 화면 크기에 대응하여 사이즈 결정하기가 좋습니다.) 320 * 480 화면 기준으로 들어갈 이미지나 UI 요소들 각각의 가로 사이즈를 px로 계산한 후 코딩시에는 그 값의 단위를 dip로만 입력하면 됩니다.

 

2. AbsoluteLayout을 사용하지 않습니다. , 화면의 절대 좌표 보다는 상대 좌표를 사용해야 합니다. 이거 사용해서 디자인하면..나중에 감당 안됩니다.

3. Bitmap HDPI 기준으로 만듭니다. 그래야 자동으로 크기가 조정 되더라도 보기에 좋습니다. , HVGA를 기준으로 계산했을 때 100 * 100 이미지가 필요하다면 HDPI 기준으로 크기의 1.5배인 150 *150 크기로 실 이미지를 제작하시면 됩니다. 만일, 여력이 된다면 hdpi mdpi 기준으로 각각 만드는 것도 나쁘지는 않습니다. 위에서 언급했듯이 성능에 유리합니다.

 

4. 각 장치별로 레이아웃 및 이미지를 모두 별도로 만들어서 세밀하게 조정할 수도 있지만, 그런 경우 관리가 힘듭니다. 가급적 레이아웃과 이미지를 적게 사용해서 통일된 UI를 구성하는 것이 좋습니다.

 
자 이제 저희 앱 개발로 돌아가겠습니다.

기획서 상의 1, 2, 3, 7 번 이미지는 HVGA상에서 32 * 32 크기로 랜더링 될 것입니다. 즉 코딩시에 가로 세로 사이즈 값에 32dip라고 입력할 것입니다. 그래서 실제 이미지는 위 가이드에 따라서 48 * 48 (32 * 1.5 = 48) 사이즈로 제작해서 drawable-hdpi 에 저장합니다.

4, 5번 이미지는 리스트에 들어갈 이미지 버튼입니다. 약간 큰 리스트로 구성할 계획이라서 코딩시 크기값은 48dip 가 되며, 실 이미지 제작은 hdpi 기준으로 64 * 64 크기로 제작합니다.

 

그리고 1, 4, 5번은 클릭시에 이미지 버튼에 효과를 주기 위해서 이미지를 쌍으로 준비합니다. iconWorkshop에서 배경에 색칠을 한다던지, GrayScale로 변경하여 만드시면 됩니다.

 

6번 이미지는 이미지로 제작한 게 아니라 xml로 정의하여 런타임시에 그린 이미지입니다.

8, 9번은 nine-patch 이미지입니다. Nine-patch 이미지는 이미지를 9분할하여 이미지 사이즈 변경시에 이쁘게 형태를 유지할 수 있도록 하는 이미지 입니다. 파일명.9.png 이런식으로 파일명이 구성되어 있습니다. 레이아웃에 지정할 때는 파일명 부분만(9.png를 제외한) 지정하시면 됩니다.  이 두 이미지는 제가 이것저것 보다가 찾은 이미지인데, 안드로이드 블랙 배경에 잘 어울리는 듯 합니다.

 

참고로 Android SDK 하위 폴더를 보시면 data/res/drawable-hdpi/ 애뮬레이터에서 사용하는 모든 이미지들이 있습니다. 좋은 것들도 많고 도움이 많이 됩니다. 구글에서 제공되는 기본 앱 디자인 스타일과 유사한 인터페이스를 제공하려면 이 이미지들을 이용하시면 됩니다.

 

이제 이미지가 모두 준비되었습니다.

다음 화면은 hdpi 폴더에 저장된 이미지 내용입니다. 위에서 언급한 내용과 이전 포스트에서 제작한 아이콘이 저장되어 있습니다.



내용이 너무 길어 읽으시는 분들이 지루할까? 여기서 레이아웃 Part1을 마치고, 잠시 후에 Part2로 찾아뵙겠습니다.


저작자 표시 비영리 변경 금지
신고
Trackback 0 Comment 3
  1. 소영 2010.09.26 12:02 신고 address edit & del reply

    아 정말 정말 정말 많은 도움이 되었어요!!
    에뮬레이터에서 기본적으로 제공되는 버튼 같은 것만 사용하다가

    이제 한번 직접 만든 이미지를 사용해서 상용화되는 앱을 만들려다보니까

    가장먼저 골치 아픈 것이 기종에 따라 다른 스크린 사이즈에서 이미지를 리사이즈 하는 것이더라구요..ㅠㅠ

    사실 아직도 -_-.. 그렇지만 여기서 정말 좋은 정보 많이 얻고 가요! 도전해봐야겠어요! ㅎㅎ

  2. 희망안드 2011.01.25 06:56 신고 address edit & del reply

    성격이 깔끔하시고 세심한 면이 많으신듯 해요
    하나하나 글쓰시는게 많은 도움이 되고
    집중력을 높이네요
    대단히 감사합니다
    강좌 계속 하시면서 책도 쓰심 대박 나실듯
    계속 강좌 부탁드려요

  3. 강민 2011.11.20 12:36 신고 address edit & del reply

    당신은 최고입니다 ㅋ
    너무 강좌가 좋네요
    교육쪽에서 일하시나? ㅋㅋㅋ
    계속 강좌 읽겠습니다 ㅠㅠ