dp(밀도 독립 픽셀)의 기본 사항을 설명합니다 — Android의 측정 단위로, 다양한 픽셀 밀도의 화면에서 UI 요소의 동일한 물리적 크기를 보장합니다. 1dp는 항상 화면에서 1/160인치에 해당하며, 기기의 해상도가 높거나 낮은 것과 관계없습니다. Google Material Design(2025)에 따르면 Android 애플리케이션의 모든 치수는 px가 아닌 dp로 지정해야 하며, 그렇지 않으면 인터페이스가 다른 기기에서 다르게 보입니다.
주요 포인트
dp(밀도 독립 픽셀)는 Android의 가상 측정 단위로, 다양한 픽셀 밀도의 기기에서 UI 요소 크기를 통일하기 위해 도입되었습니다. 1dp는 160dpi 밀도(mdpi)의 화면에서 대략 하나의 물리적 픽셀과 같습니다. 320dpi 밀도(xhdpi)의 화면에서 1dp는 2개의 물리적 픽셀과 같습니다. 따라서 화면에서 요소의 물리적 크기는 동일하게 유지됩니다 — 약 1/160인치입니다. Android Developers(2025)에 따르면 dp는 레이아웃, 패딩, 마진 및 뷰 너비/높이 치수에 사용해야 하는 유일한 측정 단위입니다.
버튼 너비를 160px로 설정하면 mdpi 화면에서 너비가 1인치이지만 xxxhdpi 화면(640dpi)에서는 0.25인치에 불과합니다. dp는 이 문제를 해결합니다. 모든 화면에서 160dp는 1인치가 됩니다. Android는 렌더링 중에 DisplayMetrics.density를 통해 dp를 px로 자동 변환합니다. Android Developer Blog(2025)에 따르면 dp(Android 1.0) 도입 전에는 개발자가 수동으로 px 오프셋을 계산했으며, 이는 포팅 시 지속적인 버그를 야기했습니다.
dp, px 및 sp는 Android의 세 가지 측정 단위로, 각각 고유한 목적이 있습니다. px는 밀도에 의존하는 물리적 화면 픽셀입니다. dp는 요소 치수를 위한 밀도 독립 픽셀입니다. sp는 텍스트를 위한 스케일 독립 픽셀로, 시스템 글꼴 크기 설정도 추가로 고려합니다. Material Design(2025)에 따르면 dp와 sp의 차이는 중요한 접근성 포인트입니다. 시력이 약한 사용자는 글꼴 크기를 늘리며, sp 값은 자동으로 조정되지만 dp는 그렇지 않습니다.
| 단위 | 전체 이름 | 밀도 고려 | 글꼴 설정 고려 | 용도 |
|---|---|---|---|---|
| px | 픽셀 | 아니요 | 아니요 | 권장하지 않음 |
| dp | 밀도 독립 픽셀 | 예 | 아니요 | 레이아웃, 패딩, 마진 |
| sp | 스케일 독립 픽셀 | 예 | 예 | 텍스트 크기 |
dp를 px로 변환하는 공식: px = dp × (dpi / 160). 역변환: dp = px / (dpi / 160). density는 dpi / 160의 비율로, Android가 DisplayMetrics를 기반으로 계산합니다. mdpi에서 density = 1.0, hdpi에서 = 1.5, xhdpi에서 = 2.0, xxhdpi에서 = 3.0, xxxhdpi에서 = 4.0입니다. 따라서 픽셀 단위의 48dp: mdpi에서 48px, xxhdpi에서 144px입니다. Google I/O 2024에 따르면 이 공식은 iOS pt(포인트)를 dp로 대략 변환하는 데 사용할 수 있습니다 — 1pt ≈ 1dp.
| 버킷 | 밀도 | dpi 값 | 48dp → px | 16dp → px |
|---|---|---|---|---|
| mdpi | 1.0 | 160 | 48 | 16 |
| hdpi | 1.5 | 240 | 72 | 24 |
| xhdpi | 2.0 | 320 | 96 | 32 |
| xxhdpi | 3.0 | 480 | 144 | 48 |
| xxxhdpi | 4.0 | 640 | 192 | 64 |
dimens.xml은 res/values/의 Android 리소스 파일로, 모든 치수를 dp(텍스트의 경우 sp)로 저장하기 위한 것입니다. dimens.xml에 치수를 중앙 집중화하면 유지 관리가 간소화됩니다. dimens.xml에서 하나의 값을 변경하면 애플리케이션의 모든 화면에서 크기가 업데이트됩니다. 다양한 밀도(values-hdpi, values-xhdpi)에 대해 한정된 dimens.xml 파일을 만들 수 있습니다. Android Jetpack Docs(2025)에 따르면 Google은 마진, 패딩, 요소 너비(상수), 아바타 크기 및 툴바 높이를 dimens.xml에 저장할 것을 권장합니다.
<resources>
<dimen name="margin_small">8dp</dimen>
<dimen name="margin_medium">16dp</dimen>
<dimen name="margin_large">24dp</dimen>
<dimen name="avatar_size">48dp</dimen>
<dimen name="toolbar_height">56dp</dimen>
<dimen name="text_size_body">14sp</dimen>
<dimen name="icon_size_small">24dp</dimen>
</resources>
이 파일에서 각 dimen에는 이름과 값이 있습니다. XML 마크업에서 사용: @dimen/avatar_size. Material Design Guidelines(2025)에 따르면 Android의 기본 그리드 단계는 8dp(8포인트 그리드)입니다. 모든 마진, 요소 크기 및 거리는 8dp의 배수여야 합니다: 8, 16, 24, 32, 48, 56, 64, 72dp. 텍스트의 단계는 4sp입니다.
XML 마크업에서 dp는 직접 사용됩니다: android:layout_width="48dp". 프로그래매틱 코드(Kotlin/Java)에서는 TypedResource 또는 확장 함수를 사용하여 dp를 px로 변환해야 합니다. TypedResource는 런타임에 dp로 작업하기 위한 준비된 메서드를 제공합니다: getDimensionPixelSize()는 정수 px 값을 반환합니다. Jetpack Compose에서 dp는 수정자 및 레이아웃 컨테이너의 표준 측정 단위입니다.
// 프로그래매틱하게 dp를 px로 변환
fun Context.dpToPx(dp: Int): Int {
return (dp * resources
.displayMetrics
.density).toInt()
}
// Activity에서 사용
val paddingPx = dpToPx(16)
button.setPadding(
paddingPx,
paddingPx,
paddingPx,
paddingPx,
)
// Jetpack Compose: 내장 단위로서의 dp
Modifier
.padding(16.dp)
.size(48.dp)
이 예제에서 dpToPx()는 Context의 확장 함수로, displayMetrics.density를 사용하여 dp를 px로 변환합니다. Jetpack Compose에서 dp는 유형 시스템에 내장되어 있으며 수동 변환이 필요하지 않습니다 — 컴파일러가 렌더링 단계에서 자동으로 dp를 px로 변환합니다.
<Button
android:layout_width="match_parent"
android:layout_height="48dp"
android:padding="@dimen/margin_medium"
android:textSize="@dimen/text_size_body"
android:text="@string/button_label"
android:layout_marginTop="16dp"
/>
XML에서 dp는 숫자의 접미사로 지정됩니다 — margin_top="16dp". 텍스트에는 sp가 사용됩니다 — textSize="@dimen/text_size_body". @dimen 참조는 중앙 집중식 값 관리를 가능하게 합니다. 너비에 match_parent를 사용하고 높이에 48dp를 사용하는 것은 버튼의 표준 Material Design 패턴입니다.
Google Play Console(2025)의 Android 애플리케이션 분석에 따르면 가장 흔한 5가지 실수는 다음과 같습니다: XML 마크업에서 px 대신 dp를 사용하지 않음, dimens.xml 부재(값이 인라인으로 작성됨), 코드에서 잘못된 dp→px 변환(정수 나누기 사용), 텍스트에 sp 무시, sp를 통한 시스템 글꼴 크기 설정 미고려. 정수 나누기가 가장 위험한 실수입니다: Kotlin에서 val px = dp * density — dp와 density가 Int이면 결과도 Int가 되어 정밀도가 손실됩니다.
자주 묻는 질문
Android의 dp와 iOS의 pt(포인트)는 동등한 측정 단위입니다. Android의 1dp는 iOS의 1pt와 거의 같습니다. 두 개념 모두 밀도 독립 포인트를 설명합니다: 저밀도의 오래된 기기에서는 1dp/pt = 1px, 현대 기기에서는 2-4px입니다. 차이는 기본 값에 있습니다: Android는 160dpi를 기본 밀도로 사용하고, iOS는 163dpi를 사용하므로 2% 미만의 오차가 발생합니다.
Jetpack Compose에서는 변환이 필요하지 않습니다 — dp가 유형 시스템에 내장되어 있습니다. 모든 수정자와 레이아웃은 px가 아닌 Dp를 허용합니다. dp에서 px를 가져와야 하는 경우 density를 사용하세요: val px = with(LocalDensity.current) { 16.dp.toPx() }. LocalDensity는 기기의 화면 밀도를 고려한 변환 계수를 제공합니다.
dp는 Android 용어입니다. iOS에서는 pt(포인트)가 이에 해당합니다. Swift는 화면 밀도와 무관한 포인트로 자동으로 작동합니다. UIKit 및 SwiftUI에서 모든 치수는 포인트로 지정되며, 시스템은 화면의 스케일 팩터(UIScreen.main.scale)를 사용하여 px로 변환합니다. 동일한 원리, 다른 이름입니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.