안드로이드 레이아웃과 DisplayMetrics.density

프로그래밍/Android 관련2018. 3. 24. 20:54

안녕하세요. 개발자 드리머즈입니다.


iOS와 비슷하게 안드로이드에서도 개발자가 레이아웃 xml파일에서 어느정도?만 UI를 잡아주면 안드로이드가 자동으로 다양한 크기의 스크린에 적절하게 보이도록 합니다. 이와 관련된 개념으로 densityresolution이 있습니다.


resolution

resolution은 해상도를 의미합니다. 예로 들면 320*480, 1080*1920등과 같은 디스플레이의 가로, 세로 픽셀 수를 의미합니다. 


density

안드로이드에서 getResources().getDisplayMetrics().density로 구할 수 있는 density는 디스플레이의 논리적인 density(밀도)를 의미합니다. 이것은 Density Independent Pixel(DIP, 밀도와 무관한 픽셀) 단위에 쓰이는 곱하기 인자(scaling factor)입니다. 1 DIP는 대략 160 dpi(예를 들어 가로1.5인치 세로 2인치의 240x320해상도를 가지는 스크린) 스크린에서 1픽셀에 해당하는데 시스템 디스플레이의 기준이 됩니다. 따라서 160 dpi 스크린에서 이 density 값은 1이 되고, 120 dpi 스크린에서 density는 0.75가 되는 식입니다.


*Density Independent Pixel(DIP)는 레이아웃 xml에 쓰이는 dp를 의미함

*dpi는 dots per inch의 약자로 1인치당 픽셀의 갯수를 의미함

*참고

https://developer.android.com/guide/practices/screens_support.html

https://developer.android.com/reference/android/util/DisplayMetrics.html#density




생각해보기

화면의 중앙에 가로 2dp, 세로 2dp의 빨간색 사각형을 그리는 상황을 생각해보겠습니다.

두 디스플레이 A와 B가 있는데 디스플레이A의 해상도는 6*6, density는 1(= 160 dpi), B의 해상도는 12*12, density는 2(=320 dpi)라고 가정해보겠습니다. 동일한 크기의 디스플레이나 B의 디스플레이 픽셀이 더 촘촘한 경우입니다.

이 경우 A 디스플레이에서 2dp 는 2픽셀(2dp*1density)에 해당하고 B 디스플레이에서 2dp는 4픽셀(2dp*2density)에 해당합니다. 

디스플레이의 중앙에 2*2 dp의 크기를 가지는 빨간색 사각형을 그린다고 하면 위의 그림처럼 됩니다. 서로 다른 디스플레이 A와 B이지만 사용자가 보기에는 똑같은 아주 이상적인(제대로 동작하는) 경우입니다.



동일한 density 2를 가지는 두 디스플레이 A와 B가 있는데 A의 해상도는 12*12, B의 해상도는 6*6이라고 가정해보겠습니다. 픽셀의 촘촘한 정도는 같지만 디스플레이 A의 크기가 더 큰 경우입니다. 디스플레이A를 타블렛의 스크린, 디스플레이B를 스마트폰의 스크린으로 볼 수 있습니다. 

이 경우 A 디스플레이에서 2dp 는 4픽셀(2dp*2density)에 해당하고 B 디스플레이에서 2dp는 4픽셀(2dp*2density)에 해당합니다. 

디스플레이의 중앙에 2*2 dp의 크기를 가지는 빨간색 사각형을 그린다고 하면 위의 그림처럼 됩니다. 디스플레이 A와 디스플레이 B 모두에서 2dp는 4pixel에 해당합니다.

이 경우 위의 동작은 원하지 않는 결과일 확률이 높습니다. 

이 경우에 문제를 해결하고자 한다면 https://developer.android.com/guide/practices/screens_support.html를 참고 바랍니다.



동일한 해상도(6*6)을 가지는 두 디스플레이 A와 B가 있는데 A의 density는 1(= 160 dpi), B의 density는 2(=320 dpi)라고 가정해보겠습니다. 

디스플레이A는 큰 디스플레이를 가지는 해상도가 낮은 저가 모델의 스크린을 예로 들 수 있으며, 디스플레이B는 작은 디스플레이를 가지는 해상도가 높은 고가 스마트폰의 모델을 예로 들 수 있습니다.


이 경우 A 디스플레이에서 2dp 는 4픽셀(2dp*1density)에 해당하고 B 디스플레이에서 2dp는 4픽셀(2dp*2density)에 해당합니다. 

디스플레이의 중앙에 2*2 dp의 크기를 가지는 빨간색 사각형을 그린다고 하면 위의 그림처럼 됩니다.  디스플레이 A에서 2dp는 2픽셀이지만, 디스플레이 B에서 2dp는 4픽셀에 해당되기 때문입니다. 이 경우에도 위의 결과는 원하지 않은 결과일 확률이 높습니다.

 이 경우에 문제를 해결하고자 한다면 https://developer.android.com/guide/practices/screens_support.html를 참고 바랍니다.




안드로이드에서 density는 어떻게 정해지는가?

안드로이드 레이아웃에서 density는 아주 중요한 역할을 하는 것 같습니다. 좀 더 알아보겠습니다.

Pixel XL 1440*2560 (5.5인치)
getResources().getDisplayMetrics().density = 3.5
getResources().getDisplayMetrics().densityDpi = 560

G5 1440*2560 (5.3인치)
getResources().getDisplayMetrics().density = 4.0
getResources().getDisplayMetrics().densityDpi = 640

위의 두 단말을 보겠습니다. Pixel XL과 LG G5의 해상도는 똑같습니다. Pixel XL이 G5보다 더 크므로 Pixel XL의 더 낮은 dpi를 가집니다. 디스플레이의 크기가 약 3.6% 차이가 나는데 density는 훨씬 더 큰 차이가 납니다. 이 것으로 보아 안드로이드에서 쓰이는 density는 물리적인 dpi와 어느정도 관련이 있긴 하지만 정비례하지는 않는다는 것을 알 수 있습니다. 그렇다면 무엇이 안드로이드의 density를 결정하는 것일까요? 아쉽게도 안드로이드 디벨로퍼 사이트에도 자세한 설명이 안나오네요. 찾게되면 여기에 기록하겠습니다.



작성자

Posted by 드리머즈

관련 글

댓글 영역