В документации сказано, что 160 dp (независимо от плотности) равняется 1 дюйму. А 72 пт тоже 1 дюйм. Поэтому я не понимаю, почему Android определяет измерение dp, хотя оно, кажется, работает так же, как точки. Кто-нибудь может это объяснить? Зачем мне использовать dp, если я могу использовать pt?
Разница между размерами Android: pt и dp
Ответы (7)
В документации 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 мм длиннее, чем я измерил линейкой.
В документации сказано, что 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
Из любопытства я попробовал макет из ответа Джона на двух своих устройствах: Asus Transformer (10,1 дюйма) и HTC Legend (3,2 дюйма). Результаты оказались довольно интересными:
Трансформер (обрезанный):
И Легенда:
Я боролся с измерениями, но я думаю, что нашел способ смотреть на это, который имеет для меня смысл. В статье 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 точек на дюйм не будут на дюйм на устройстве ... закрыть выше или ниже, но не совсем
pt Точки – 1/72 дюйма в зависимости от физического размера экрана.
dp Пиксели, не зависящие от плотности — абстрактная единица измерения, основанная на физической плотности экрана. Эти единицы относятся к экрану с разрешением 160 точек на дюйм, поэтому один dp равен одному пикселю на экране с разрешением 160 точек на дюйм. Отношение dp к пикселю будет меняться в зависимости от плотности экрана, но не обязательно прямо пропорционально. Примечание. Компилятор принимает как "dip", так и "dp", хотя "dp" больше соответствует "sp".
Зачем мне использовать 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
1 dp всегда будет равен 1/160 дюйма, независимо от плотности экрана.
Это не так, как показано в вашем приложении... Согласны?
БР СТЭН