В документации сказано, что 160 dp (независимо от плотности) равняется 1 дюйму. А 72 пт тоже 1 дюйм. Поэтому я не понимаю, почему Android определяет измерение dp, хотя оно, кажется, работает так же, как точки. Кто-нибудь может это объяснить? Зачем мне использовать dp, если я могу использовать pt?
Разница между размерами Android: pt и dp
Ответы (7)
78
В документации Android неправильно указано, что 160 dp всегда равняется 1 дюйму независимо от плотности экрана. Об этом было сообщено как об ошибке, которая была принята, а документация обновлена. .
Из обновленной документации:
160 dp НЕ всегда будет равно 1 дюйму, оно будет варьироваться в зависимости от размера и плотности экрана. На экране с плотностью 160 dpi (mdpi) 160 dp будет равняться 1 дюйму.
1 pt всегда будет равен 1/72 дюйма, независимо от плотности экрана.
Документация по Android для этого находится здесь.
ОБНОВЛЕНИЕ:
Я сделал небольшое приложение, чтобы попробовать и проверить разные размеры. Похоже, то, что выше, верно, по крайней мере, когда оно показано на моем HTC Aria. Вот скриншот:

Интересно отметить, что эти размеры НЕ точно совпадают в графическом редакторе eclipse. Размеры dp и sp колебались в зависимости от размера экрана и разрешения в редакторе. Вот несколько скриншотов из редактора (слева — 2,7-дюймовый слайдер QVGA, справа — 10,1-дюймовый WXGA, обрезанный):

Было бы интересно посмотреть, совпадают ли рендеры этих редакторов с реальными устройствами. Кто-нибудь может проверить эти размеры? Я прикреплю свой xml ниже, если кто-то захочет помочь.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="160dp"></TextView>
<View android:id="@+id/view1" android:layout_height="20dip" android:layout_width="160dp" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="72pt"></TextView>
<View android:id="@+id/view2" android:layout_height="20dip" android:layout_width="72pt" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="1in"></TextView>
<View android:id="@+id/View01" android:layout_height="20dip" android:layout_width="1in" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:layout_width="wrap_content" android:textSize="22sp" android:layout_height="wrap_content" android:text="160sp" android:padding="5sp" android:id="@+id/TextView01"></TextView>
<View android:layout_marginLeft="20sp" android:layout_width="160sp" android:id="@+id/View04" android:background="#FF22FF22" android:layout_height="20dip"></View>
<TextView android:layout_width="wrap_content" android:textSize="22sp" android:layout_height="wrap_content" android:padding="5sp" android:id="@+id/TextView02" android:text="160px"></TextView>
<View android:layout_marginLeft="20sp" android:id="@+id/View03" android:background="#FF22FF22" android:layout_height="20dip" android:layout_width="160px"></View>
<TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="25.4mm"></TextView>
<View android:id="@+id/View02" android:layout_height="20dip" android:layout_marginLeft="20sp" android:background="#FF22FF22" android:layout_width="25.4mm"></View>
</LinearLayout>
Изменить: к примеру Джона добавлено еще 2 устройства. Слева Samsung Nexus S (ОС 2.3.3). Справа Samsung Galaxy Tab 10.1 (ОС 3.1). Никаких модов.


На Nexus S 160dp немного больше 1 дюйма. Все обычные физические единицы измерения (дюймы, мм, точки) имеют одинаковый размер. Я измерил его линейкой, и полоса 160 dp примерно на 1 мм больше, чем должна. В то время как физические единицы на 1 мм короче, чем должны.
На вкладке все полосы точно такие же и на 1 мм длиннее, чем я измерил линейкой.
39
В документации сказано, что 160 dp (независимо от плотности) равняется 1 дюйму. А 72 пт тоже 1 дюйм.
Нюанс здесь в том, что 160 dp (или dip) составляет примерно 1 дюйм, а 72 pt ровно 1 дюйм. Разница в том, как андроид преобразует обе единицы в пиксели, что зависит от плотности экрана устройства.
Один dp — это один px на устройстве с разрешением 160 dpi. Android использует «ковш плотности», в который попадает устройство, и умножает скейлер для преобразования dp в px.
Bucket | DPI | Scaler
---------------------
ldpi | 120 | 0.75
mdpi | 160 | 1.00
tvdpi | 213 | 1.33
hdpi | 240 | 1.50
xhdpi | 320 | 2.00
xxhdpi | 480 | 3.00
dp в px преобразуется по следующей формуле: dp * scaler = px.
Одно pt равно 1/72 дюйма при любой плотности экрана. Android преобразует pt в px, используя точное значение dpi (xdpi и ydpi) экрана устройства.
pt в px преобразуется по следующей формуле: pt / 72 * dpi = px.
Поэтому я не понимаю, почему Android определяет измерение dp, хотя оно, кажется, работает так же, как точки. Кто-нибудь может это объяснить? Зачем мне использовать dp, если я могу использовать pt?
Возьмем, к примеру, отображение 160 dp и 72 pt на устройстве с разрешением 160 dpi. Устройство с разрешением 160 dpi попадает в корзину плотности mdpi с коэффициентом масштабирования 1,0. Используйте приведенные выше формулы для преобразования в px.
160 dp * 1.0 = 160 px
72 pt / 72 * 160 = 160 px
А как насчет устройства с разрешением 170 dpi? Устройство с разрешением 170 dpi попадает в корзину плотности mdpi с коэффициентом масштабирования 1,0.
160 dp * 1.0 = 160 px
72 pt / 72 * 170 = 170 px
Как насчет устройства с разрешением 150 dpi? Устройство с разрешением 150 dpi попадает в корзину плотности mdpi с масштабированием 1,0.
160 dp * 1.0 = 160 px
72 pt / 72 * 150 = 150 px
Мораль этой истории такова: dp сохраняет точные размеры и помогает поддерживать производительность, допуская некоторые вариации физических размеров в зависимости от плотности устройства. С другой стороны, pt имеет одинаковый физический размер для каждой плотности, что приводит к использованию разного количества px, что может снижать производительность и вызывать алиасинг и артефакты при использовании на изображениях. dp рекомендуется, если только не требуются абсолютно точные физические размеры (у вас есть линейка на экране и т. д.).
Я написал подробный блог о единицах измерения Android, в котором содержится дополнительная информация и примеры кода — Понимание Независимость от плотности в Android
3
Из любопытства я попробовал макет из ответа Джона на двух своих устройствах: Asus Transformer (10,1 дюйма) и HTC Legend (3,2 дюйма). Результаты оказались довольно интересными:
Трансформер (обрезанный):

И Легенда:

3
Я боролся с измерениями, но я думаю, что нашел способ смотреть на это, который имеет для меня смысл. В статье Wei-Meng Lee «Начало разработки приложений для Android 4» (стр. 111) есть формула преобразования:
Фактические пиксели = dp * ( dpi / 160 ), где dpi равно 120, 160, 240 или 320.
Итак, используя эту формулу, я могу найти, какое значение dpi для моего телефона/эмулятора ближе всего к одному из этих четырех значений, и это определит соотношение (3/4, 1, 3/2 или 2), используемое в формуле для преобразования дп в пиксели. Для меня важно, что dpi в формуле может принимать только одно из этих четырех значений, несмотря на фактическую плотность пикселей устройства.
Ссылка на: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density для Nexus S с плотностью пикселей 235 dpi преобразование:
пиксели = дп * 3/2
Таким образом, кнопка 160 dp, скажем, будет иметь размер 240 пикселей (чуть шире дюйма при разрешении устройства 235 dpi).
Для HTC Legend с плотностью пикселей 181 dpi формула выглядит так:
пиксели = дп * 1
(потому что 181 ближе всего к 160). Таким образом, размер кнопки 160dp будет равен 160 пикселям, или чуть меньше дюйма на устройстве с плотностью пикселей 181 dpi.
Это помогает мне понять неправильность предыдущей документации Android «1 dp всегда будет равняться 1/160 дюйма, независимо от плотности экрана».
Это два основных момента, которые я пытаюсь вбить себе в голову :)
- диапазон фактической плотности пикселей устройства (например: 141-199) приведет к тому же коэффициенту (1) в формуле преобразования
- но если плотность пикселей конкретного устройства составляет ровно 160 точек на дюйм, 160 точек на дюйм не будут на дюйм на устройстве ... закрыть выше или ниже, но не совсем
3
pt Точки – 1/72 дюйма в зависимости от физического размера экрана.
dp Пиксели, не зависящие от плотности — абстрактная единица измерения, основанная на физической плотности экрана. Эти единицы относятся к экрану с разрешением 160 точек на дюйм, поэтому один dp равен одному пикселю на экране с разрешением 160 точек на дюйм. Отношение dp к пикселю будет меняться в зависимости от плотности экрана, но не обязательно прямо пропорционально. Примечание. Компилятор принимает как "dip", так и "dp", хотя "dp" больше соответствует "sp".
2
Зачем мне использовать dp, если я могу использовать pt?
Разработчики привыкли думать о вещах с точки зрения пикселей. Пиксели, не зависящие от плотности, были способом Android приблизиться к тому, к чему привыкли разработчики. При этом вы можете использовать точки, дюймы или миллиметры, если хотите.
dip на 160 и меняю dip на inch, какая разница, чем ?
- person Pacerier; 21.10.2011
dip на 160, умножу на 72 и изменю dip на pt, какая разница, чем ?
- person Pacerier; 22.10.2011
dip с ошибками или pt с ошибками?
- person Pacerier; 25.10.2011
pt постоянно совпадает с in.
- person John Leehey; 25.10.2011
pt предпочтительнее dip?
- person Pacerier; 26.10.2011
dp не соответствует реальному дюйму, а измерения pt и in не являются неправильными? Нужна линейка... но если предположить, что измерение in всегда правильное, то оказывается, что pt будет более точным для измерения точной длины.
- person John Leehey; 27.10.2011
0
1 dp всегда будет равен 1/160 дюйма, независимо от плотности экрана.
Это не так, как показано в вашем приложении... Согласны?
БР СТЭН