Swifter {Swift Developer}

메뉴

Android의 DP는?

Android 앱 개발시 디자인에서 반드시 이해야할 부분중 하나가 바로 DP라는 것이다. DP(Density-Independent pixcels)는 밀도가 독립적인 픽셀이라고 말하며, DIP라고 이야기하기도 한다.

이를 통해 Android는 DP를 통해 다양한 기기를 지원할 수 있게 된것이다.

DP를 사용 하지 않은 경우 해상도에 따라 크기가 달라진다.

density-test-bad

DP를 사용한 경우 해상도가 달라져도 크기가 유지된다.

density-test-good

관련 참고자료: Google Supporting Multiple Screens , Google More Resource Types

즉, DP를 이해하려면 필수적으로 알아야 할 요소가 PX(픽셀)과 DPI(화면밀도)이다.

PX는 하드웨어에서 구현되는 해상도 자체를 말한다. Android에서는 기기에 의해 화면해상도가 달라질수 있기 때문에 PX에서 요소를 볼 때 화면해상도에 따라 표시되는 실제크기가 달라진다. Android 앱에서는 픽셀을 직접 취급하는 경우는 극히 제한되어 있기 때문에 대부분 이미지 편집 및 OpenGL만 가능하다. (DP를 사용하지 않는 경우 이미지 참조)

DPI(Dots Per Inch)는 화면밀도로 1인치 속에 점이 몇개포함되었는지를 나타내며 그대로 Screen Density로 표현된다. 같은 FullHD해상도를 가진 기기에서 스마트폰과 태블릿이 이 DPI가 다르기 때문에 Android에서는 PX와 DPI를 고려한 DP라는 단위가 필요하게 된 것이다. 즉, 실제 DIP는 기기마다 다르기 때문에 개별적으로 지원한다는 것은 어불성설이다. 이리하여 Android에서는 DPI를 범위별로 분류하였고 이 분류로 된 화면빌도는 범용밀도(Generalized density)라고 한다.

generallized-density

관련 참고자료: Google Supporting Multiple Screens , Devices and Displays

DP는 밀도가 독립적인 픽셀로 어떤 화면의 밀도에서도 동일하게 볼 수 있는 픽셀을 말한다. DP에서 지정한 값을 화면 밀도에 따라 계산하고 실제 기기에서 볼 수 있는 PX로 변환하는 것이다.

이 PX을 표시해  보면 어떤 기기에서도 동일하게 표시되기 때문에 밀도에 독립된 픽셀이라고 부른다. 다만, 여기서 이야기하고 있는 밀도는 범용 밀도로 실제 DPI가 범용 밀도 기준 DPI에서 벗어나게 되면 다소 표시되는 크기는 차이가 발생한다. 범용 밀도에서는 이 문제를 고려하여 아주 작은 범위를 설정하고 있지만, 엄밀하게 말하면 같은 크기로 표시되는 것은 아니라는 것이다.

범용 밀도와 DP, PX의 관계를 살펴보면 다음과 같다.  참고로 LDPI 배율이 0.75배이기 때문에 DP지정은 4배수로 설정하는 것을 추천한다.

  • LDPI (x0.75) = 4DP = 3PX
  • MDPI (x1) = 4DP = 4PX
  • HDPI (x1.5) = 4DP = 6PX
  • XHDPI (x2) = 4DP = 8PX
  • XXHDPI (x3) = 4DP = 12PX
  • XXXHDPI (x4) = 4DP = 16PX

그외 DP와 비슷한 단위가 SP(Scale-Independent pixels)가 있다. 이것은 문자크기를 지정시 사용하는데 화면 밀도 외에 글꼴 크기 설정도 고려되어 있다.

 

터미널 DP 해상도

DP의 가장 큰 장점은 터미널 DP 해상도를 어느정도 좁힌다는 것이다. 범용 밀도의 범위는 기기의 화면크기를 DP로 나타낼 때 잘 겹치도록 설정되어 있어 대부분의 기기에서 일정한 DP해상도 범위에 들어간다. 스마트폰의 경우 320~410dp내에 들어간다고 한다.

  • Galaxy S (480x800px, HDPI) = 320x534dp
  • Galaxy Nexus (720x1280px, XHDPI) = 360x640dp
  • Nexus5 (1080x1920px, XXDPI) = 360x640dp
  • Nexus6 (1440x2560px, 560dpi) = 410x730dp
  • Nexus6P (1440x2560px, 560dpi) = 410x730dp

대부분이 Android기기드이 실제 해상도의 차이에 관계없이 320~410dp안에 포함된다. 즉 앱디자인을 할 때 320~410dp이내에서 망가지지 않는 레이아웃을 만들면 디자인이 깨지지 않는다.

 

DP와 이미지

Android에서 아이콘등의이미지를 만들 때 범용 밀도별로 알맞은 해상도를 가진 이미지를 준비해야 한다. 이런 이미지들도 우선은 DP기준으로 디자인하고 각 화면밀도에 따라 필요한 픽셀을 계산하는 것이 좋다. 예로 아래와 같이 아이콘을 제공하려고 한다면, 가로세로 48dp에서 상하좌우 여백8dp씩 가지는 32dp의 내부 디자인영역으로 구성한다.

android-icon

이 아이콘을 범용 밀도별로 처리하면 다음과 같은 픽셀값이 된다.

  • ldpi = 36x36px = 디자인영역 24px, 여백 6px
  • mdpi= 48x48px = 디자인영역 32px, 여백 8px
  • hdpi = 72x72px = 디자인영역 72px, 여백 12px
  • xhdpi = 96x96px = 디자인영역 64px, 여백 16px
  • xxhdpi = 144x144px = 디자인영역 96px, 여백 24px
  • xxxhdpi = 192x192px = 디자인영역 128px, 여백 32px

다만, dp는 물리적으로 상당히 작은 기기나 일반적인 밀도 기준을 벗어난 기기에서는 dp로 계산된 해상도가 달라진다. 물론 규칙에 벗어난 기기이기 때문에 크게 신경쓰지 않아도 된다.

또한 요즘 나오는 스마트폰의 대부분 해상도는 Half-HD(1280×720), FullHD(1920×1080), WQHD(2560×1440)로 되어 있고 대부분 360x640dp이다.

 

레이아웃

스마트폰 화면 너비가 320~410dp 이면 우선 320dp에 배치한다. 320dp에서 각 요소를 배치하고 410dp의 경우 어떤 레이아웃이 될지를 고려한다. 즉, 각 요소 크기를 조절하거나 여백이 늘어날 경우 부자연스러운 레이아웃이 되지 않도록 고민해야 된다. 이때, RelativeLayout을 사용하거나 LinearLayout의 ‘android: layout_weight’을 사용하면 자연스럽게 처리할 수 있다. 스마트폰에서 가로보기를 지원하는 경우 730dp까지 나오는 기기도 있기 때문에 다른 레이아웃으로 변경되게 할지를 고민해야 된다. (태블릿관련)

세로방향에 대해서는 480~730dp에 포함되는 경우가 대부분이지만, 너비와 다르게 기기의 화면비율에 따라 큰 차이가 발생한다. ListView와 GridView등 세로 스크롤 요소를 잘 사용하고 여백이 넓게 퍼지지 않도록 주의한다. 480dp 세로측면도 화면 회전에 대응하게 되면 스크롤 영역을 고려해야 한다.

 

태블릿과 DP

최근 태블릿 해상도는 16:10 비율인 1280x800px, 1920x1200px, 2560x1600px가 대부분이지만, 화면크기로 인해 스마트폰과 일반밀도가 다르다는 것을 기억해야 한다. 구글문서에 따르면 DP해상도는 짧은쪽이 600~800dp, 긴쪽이 960~1280dp범위에 들어간다고 봐야 한다.

tablet-dp

  • Nexus 7 (1920x1200px, xhdpi) = 960x600dp
  • Nexus 10 (2560x1600px, xhdpi) = 1280x800dp
  • Nexus 9 (2048x1536px, xhdpi) = 1024x768dp

태블릿을 구분하는 방법은 측면길이가 600dp이상(sw600dp)라는 조건을 이용하는 경우가 많지만, API Level13에 추가된 플러그인미만인 경우 태블릿을 구분하기는 어렵다. 이런 이유로 화면의 실제크기에 따라 지정하는(large/xlarge)를 사용하는 경우가 있다. res/layout-xlarge (API Level13미만), res/layout-sw600dp(API Level 13이상)으로 구분하게 되는 국내에서는 대부분 API Level13이하 버전을 사용하는 태블릿은 찾아보기 힘들다.

너비가 아닌 측면길이를 사용하는 것은 단순하게 너비 800dp(w800dp)를 가지고 구분하는 경우는 세로방향의 태블릿은 포함되지 않고 너비 600dp(w600dp)는 가로 스마트폰이 포함될 가능성이 있기 때문이다. 반대로 태블릿이나 스마트폰 구분없이 멀티화면을 구현한다면 너비 600dp(w600dp)로 충분하다고 볼 수 있다.

즉, 태블릿은 가로화면이라는 기준은 생각하지 말자. 추천하는 레이아웃 방법은 모든 기기를 가로  320dp(또는 300dp)별로 분류한다.

  • res/values/values.xml = <integer name=”columns”>1</integer>
  • res/values-w600dp/values.xml = <integer name=”columns”>2</integer>
  • res/values-w900dp/values.xml = <integer name=”columns”>3</integer>
  • res/values/values-w1280dp.xml = <integer name=”columns”>4</integer>

위와 같이 정의된 integer리소스를 RecyclerView와 GridView 열수로 지정하는 것으로 스마트폰 세로는 1열,태블릿 세로 2열, 소형 태블릿 3열, 큰 태블릿 4열이라는 형태로 기기 화면영역에 따라 콘텐츠 밀도를 조절할 수 있다. 물론 이런 레이아웃은 모든 앱에 사용할 수 있는 것은 아니기 때문에 세로크기가 중요한 레이아웃에서는 port와 land를 사용하여 기기 방향에 따라 대체 자원을 제공하는 것도 생각해야 한다. 이 경우, sw600dp-land, sw960dp-land처럼 측면길이를 정확하게 판단해야 한다.

Facebook Comments

카테고리:   잡담

댓글

죄송하지만 댓글은 닫혀 있습니다.