dp — основи, пиксели независими от плътността в Android

Автор: IT Sectr Публикувано: 2026-02-25 Време за четене: 7 мин

Обясняваме основите на dp (density-independent pixel) — мерна единица в Android, която осигурява еднакъв физически размер на UI елементите на екрани с различна плътност на пикселите. Един dp винаги съответства на 1/160 инча на екрана, независимо от това дали устройството има висока или ниска резолюция. Според Google Material Design (2025), всички размери в Android приложенията трябва да се задават в dp, а не в px, в противен случай интерфейсът ще изглежда различно на различни устройства.

Основни точки

  • dp (density-independent pixel) — абстрактна мерна единица в Android, равна на 1/160 инча на екрана.
  • Формула за конвертиране: px = dp × (dpi / 160). На mdpi екран 1 dp = 1 px, на xxhdpi 1 dp = 3 px.
  • Всички размери в XML (layout_width, padding, margin) се задават в dp.
  • dimens.xml — файл с ресурси на Android за централизирано съхранение на стойности dp.
  • Според Google Android Performance Guide (2025), използването на dp вместо px елиминира 90% от проблемите с адаптирането на интерфейса на различни екрани.

Какво е dp в Android?

dp (density-independent pixel) — е виртуална мерна единица в Android, въведена за унифициране на размерите на UI елементи на устройства с различна плътност на пикселите. Един dp е приблизително равен на един физически пиксел на екран с плътност 160 dpi (mdpi). На екран с плътност 320 dpi (xhdpi) 1 dp ще бъде равен на 2 физически пиксела. По този начин физическият размер на елемента на екрана остава същият — около 1/160 инча. Според Android Developers (2025), dp е единствената мерна единица, която трябва да се използва за размери на layout, padding, margin и ширина/височина на view.

Защо не може да се използва px

Ако зададете ширина на бутон от 160 px, на mdpi екран той ще бъде широк 1 инч, а на xxxhdpi екран (640 dpi) — само 0.25 инча. dp решава този проблем: 160 dp на всеки екран ще бъде равно на 1 инч. Android автоматично конвертира dp в px чрез DisplayMetrics.density при изобразяване. Според Android Developer Blog (2025), преди въвеждането на dp (Android 1.0) разработчиците използваха px ръчно изчислявайки разстояния, което водеше до постоянни грешки при портиране.

dp, px и sp: каква е разликата

dp, px и sp — три мерни единици в Android, всяка със своето предназначение. px — физическият пиксел на екрана, който зависи от плътността. dp — пиксел независим от плътността за размери на елементи. sp — scale-independent pixel за текст, който допълнително взема предвид системните настройки за размер на шрифта. Според Material Design (2025), разликата между dp и sp е ключов аспект на достъпността: потребителите с лошо зрение увеличават шрифта и стойностите sp се настройват автоматично, докато dp — не.

ЕдиницаПълно имеВзема предвид плътносттаВзема предвид настройки на шрифтаПриложение
pxPixelНеНеНе се препоръчва
dpDensity-independent PixelДаНеLayout, padding, полета
spScale-independent PixelДаДаРазмер на текст

Формула за конвертиране на dp в px и обратно

Формула за конвертиране 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. Следователно, 48 dp в пиксели: на mdpi — 48 px, на xxhdpi — 144 px. Според Google I/O 2024, тази формула може да се използва за приблизително конвертиране на iOS pt (points) в dp — 1 pt ≈ 1 dp.

BucketDensityСтойност dpi48 dp в px16 dp в px
mdpi1.01604816
hdpi1.52407224
xhdpi2.03209632
xxhdpi3.048014448
xxxhdpi4.064019264

dimens.xml: централизирано управление на размери

dimens.xml — файл с ресурси на Android в res/values/, предназначен за съхранение на всички размери в dp (и sp за текст). Централизацията на размери в dimens.xml опростява поддръжката: промяната на една стойност в dimens.xml актуализира размера на всички екрани на приложението. Могат да се създават квалифицирани dimens.xml файлове за различни плътности (values-hdpi, values-xhdpi). Според Android Jetpack Docs (2025), Google препоръчва съхранение в dimens.xml на разстояния (margin, padding), ширини на елементи (константи), размери на аватари и височина на лентата с инструменти.

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 е 8 dp (8-point grid). Всички разстояния, размери на елементи и отстояния трябва да бъдат кратни на 8 dp: 8, 16, 24, 32, 48, 56, 64, 72 dp. За текст стъпката е 4 sp.

Програмно използване на dp в Kotlin и XML

В XML файловете dp се използва директно: android:layout_width="48dp". В програмен код (Kotlin/Java) е необходимо да конвертирате dp в px с помощта на TypedResource или разширяващи функции. TypedResource предоставя готови методи за работа с dp по време на изпълнение: getDimensionPixelSize() връща цяло число px. В Jetpack Compose dp е стандартната мерна единица в модификатори и layout контейнери.

Kotlin
// Програмно конвертиране на 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, която конвертира dp в px използвайки displayMetrics.density. В Jetpack Compose dp е вградено в типовата система и не изисква ръчно конвертиране — компилаторът автоматично превежда dp в px на етапа на изобразяване.

XML файлове с dp

XML

<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 за бутони.

Типични грешки при използване на dp

Според анализ на Android приложения от Google Play Console (2025), петте най-чести грешки са: използване на px вместо dp в XML файлове, липса на dimens.xml (стойности написани inline), неправилно конвертиране на dp в px в код (използване на целочислено деление), игнориране на sp за текст и неотчитане на системните настройки за размер на шрифта чрез sp. Целочисленото деление е най-опасната грешка: в Kotlin val px = dp * density — ако dp и density са Int, резултатът също ще бъде Int и точността се губи.

  • px вместо dp — приложението изглежда различно на устройства с различна плътност. Поправка: замяна на px с dp в XML.
  • Inline стойности — размерите са написани директно в layout файлове. Дублирането на стойности усложнява поддръжката и актуализирането.
  • sp за текст — използването на dp за размер на шрифта игнорира настройките на потребителя, нарушавайки достъпността.
  • Целочислено деление — в Kotlin делението на Int на Int дава Int, губейки дробната част. Винаги използвайте Float.

Често задавани въпроси

Как се различава dp от pt в iOS?

dp в Android и pt (points) в iOS — са еквивалентни мерни единици. 1 dp в Android е приблизително равен на 1 pt в iOS. И двете понятия описват точки независими от плътността: на стари устройства с ниска плътност 1 dp/pt = 1 px, на модерни — 2-4 px. Разликата в базовата стойност: Android използва 160 dpi като базова плътност, iOS — 163 dpi, което дава грешка под 2%.

Как да конвертираме dp в px в Jetpack Compose?

В Jetpack Compose не е необходимо конвертиране — dp е вградено в типовата система. Всички модификатори и layout приемат Dp, а не px. Ако трябва да получите px от dp, използвайте density: val px = with(LocalDensity.current) { 16.dp.toPx() }. LocalDensity предоставя коефициент за конвертиране, който отчита плътността на екрана на устройството.

Трябва ли да използвам dp в iOS?

dp — термин на Android. В iOS аналогът е pt (points). Swift автоматично работи с точки, които не зависят от плътността на екрана. В UIKit и SwiftUI всички размери се задават в точки, а системата ги конвертира в px чрез scale factor на екрана (UIScreen.main.scale). Принципът е същият, името е различно.

Обобщение

  • dp — Density-independent Pixel, абстрактна единица за UI размери в Android, равна на 1/160 инча.
  • Формула: px = dp × (dpi / 160). На mdpi 1 dp = 1 px, на xxhdpi 1 dp = 3 px.
  • Всички размери в XML файлове трябва да се задават в dp, размер на текста — в sp.
  • dimens.xml — централизирано съхранение на размери. Една промяна актуализира целия интерфейс.
  • 8-point grid: всички размери са кратни на 8 dp, разстояния на текст — 4 sp.
  • В програмен код използвайте TypedResource или разширяващи функции за конвертиране на dp в px.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също