Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Разница между размерами Android: pt и dp

Автор вопроса: HerbertОтветов: 7

В документации сказано, что 160 dp (независимо от плотности) равняется 1 дюйму. А 72 пт тоже 1 дюйм. Поэтому я не понимаю, почему Android определяет измерение dp, хотя оно, кажется, работает так же, как точки. Кто-нибудь может это объяснить? Зачем мне использовать dp, если я могу использовать pt?

  • Документация Android была обновлена, чтобы удалить неверное утверждение о том, что 160 dp равняется 1 дюйму. Intrications 17.03.2012

androidmeasurementdimension

Ответы

Ответ 1 · рейтинг 78 · John Leehey

В документации 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 мм длиннее, чем я измерил линейкой.

Ответ 2 · рейтинг 39 · Steven Byle

В документации сказано, что 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 · рейтинг 3 · howettl

Из любопытства я попробовал макет из ответа Джона на двух своих устройствах: Asus Transformer (10,1 дюйма) и HTC Legend (3,2 дюйма). Результаты оказались довольно интересными:

Трансформер (обрезанный):

И Легенда:

Ответ 4 · рейтинг 3 · gcbound

Я боролся с измерениями, но я думаю, что нашел способ смотреть на это, который имеет для меня смысл. В статье 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 дюйма, независимо от плотности экрана".

Это два основных момента, которые я пытаюсь вбить себе в голову :)

  1. диапазон фактической плотности пикселей устройства (например: 141-199) приведет к тому же коэффициенту (1) в формуле преобразования
  2. но если плотность пикселей конкретного устройства составляет ровно 160 точек на дюйм, 160 точек на дюйм не будут на дюйм на устройстве ... закрыть выше или ниже, но не совсем

Ответ 5 · рейтинг 3 · Subayan

pt Точки - 1/72 дюйма в зависимости от физического размера экрана.

dp Пиксели, не зависящие от плотности - абстрактная единица измерения, основанная на физической плотности экрана. Эти единицы относятся к экрану с разрешением 160 точек на дюйм, поэтому один dp равен одному пикселю на экране с разрешением 160 точек на дюйм. Отношение dp к пикселю будет меняться в зависимости от плотности экрана, но не обязательно прямо пропорционально. Примечание. Компилятор принимает как "dip", так и "dp", хотя "dp" больше соответствует "sp".

Ответ 6 · рейтинг 2 · CommonsWare

Зачем мне использовать dp, если я могу использовать pt?

Разработчики привыкли думать о вещах с точки зрения пикселей. Пиксели, не зависящие от плотности, были способом Android приблизиться к тому, к чему привыкли разработчики. При этом вы можете использовать точки, дюймы или миллиметры, если хотите.

Ответ 7 · STeN

1 dp всегда будет равен 1/160 дюйма, независимо от плотности экрана.

Это не так, как показано в вашем приложении... Согласны?

БР СТЭН

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы