web-dev-qa-db-fra.com

Différence entre Android dimension: pt et dp

La documentation indique que 160 dp (indépendant de la densité) est égal à 1 pouce. Et 72 pt est également de 1 pouce. Je ne vois donc pas pourquoi Android définir une mesure dp alors qu'elle semble fonctionner de la même manière que les points. Quelqu'un peut-il expliquer cela? Pourquoi devrais-je utiliser dp si je peux utiliser pt?

51
Herbert

La documentation Android utilisée pour indiquer de manière incorrecte que 160 dp est toujours égale à 1 pouce quelle que soit la densité de l'écran. Cela a été signalé comme bug qui a été accepté et la documentation mise à jour.

De la documentation mise à jour:

160 dp n'équivaudra PAS toujours à 1 pouce, il variera en fonction des différentes tailles et densités d'écran. Sur un écran avec une densité de 160 dpi (mdpi), 160 dp sera égal à 1 pouces.

1 pt sera toujours égal à 1/72 po, quelle que soit la densité de l'écran.

La documentation Android pour cela est ici .

MISE À JOUR:

J'ai fait une petite application pour essayer de vérifier les différentes tailles. Il semble que ce qui est ci-dessus soit correct, du moins lorsqu'il est affiché sur mon HTC Aria. Voici une capture d'écran:

HTC Aria resource type test

Il est intéressant de noter que ces tailles ne correspondent PAS exactement dans l'éditeur graphique Eclipse. Les tailles dp et sp ont varié en fonction de la taille de l'écran et de la résolution dans l'éditeur. Voici quelques captures d'écran de l'éditeur (le curseur QVGA de 2,7 pouces à gauche, le WXGA 10,1 pouces à droite, coupé):

enter image description here

Il serait intéressant de voir si ces éditeurs correspondent aux périphériques réels. Quelqu'un peut-il vérifier ces tailles? J'attacherai mon xml ci-dessous au cas où quelqu'un voudrait aider.

<?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>

Edit: Ajout de 2 appareils supplémentaires à l'exemple de John. A gauche un Samsung Nexus S (OS 2.3.3). A droite, un Samsung Galaxy Tab 10.1 (OS 3.1). Pas de mods.

Samsung Nexus SSamsung Galaxy Tab 10.1

Sur le Nexus S, 160dp est légèrement supérieur à 1 pouce. Toutes les unités physiques normales (in, mm, pt) sont toutes de la même taille. Je l'ai mesuré avec une règle et la barre de 160 dp est environ 1 mm plus grande qu'elle ne devrait. Alors que les unités physiques sont 1 mm plus courtes qu'elles ne le devraient.

Sur l'onglet, toutes les barres sont exactement les mêmes et 1 mm de plus que ce que j'ai mesuré avec une règle.

74
John Leehey

La documentation indique que 160 dp (indépendant de la densité) est égal à 1 pouce. Et 72 pt est également de 1 pouce.

La nuance ici est que 160 dp (ou dip) est environ 1 pouce, tandis que 72 pt est exactement 1 pouce. La différence est de savoir comment Android convertit les deux unités en pixels, ce qui dépend de la densité d'écran de l'appareil.


Un seul dp est un seul px sur un périphérique à 160 dpi. Android utilise le "seau de densité" dans lequel l'appareil tombe et multiplie un scaler pour convertir dp en 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 en px convertit en suivant cette formule: dp * scaler = px.


Un seul pt fait exactement 1/72 de pouce sur n'importe quelle densité d'écran. Android convertit pt en px en utilisant le dpi exact (xdpi et ydpi) de l'écran de l'appareil.

pt en px convertit en suivant cette formule: pt / 72 * dpi = px.


Je ne vois donc pas pourquoi Android définir une mesure dp alors qu'elle semble fonctionner de la même manière que les points. Quelqu'un peut-il expliquer cela? Pourquoi devrais-je utiliser dp si je peux utiliser pt?

Prenons un exemple, affichez 160 dp et 72 pt sur un périphérique à 160 dpi. Un périphérique de 160 dpi tombe dans le seau de densité mdpi, avec une échelle de 1,0. Utilisez les formules ci-dessus pour convertir en px.

160 dp * 1.0 = 160 px
72 pt / 72 * 160 = 160 px

Et sur un appareil à 170 dpi? Un périphérique de 170 dpi tombe dans le seau de densité mdpi, avec une échelle de 1,0.

160 dp * 1.0 = 160 px
72 pt / 72 * 170 = 170 px

Et sur un appareil à 150 dpi? Un périphérique de 150 dpi tombe dans le seau de densité mdpi, avec une échelle de 1,0.

160 dp * 1.0 = 160 px
72 pt / 72 * 150 = 150 px

La morale de l'histoire est que dp conserve les dimensions exactes et aide à maintenir les performances, permettant une certaine variation de la taille physique en fonction de la densité de l'appareil. D'un autre côté, pt a exactement la même taille physique à chaque densité, ce qui conduit à une quantité différente de px utilisée, ce qui peut nuire aux performances et provoquer des alias et des artefacts si elle est utilisée sur les images . dp est recommandé sauf si des dimensions physiques absolument exactes sont requises (vous avez une règle à l'écran, etc.).

J'ai écrit un blog détaillé sur les unités de dimension d'Android, qui donne plus d'informations et un exemple de code - Comprendre l'indépendance de la densité dans Android

38
Steven Byle

Par curiosité, j'ai essayé la mise en page de la réponse de John sur mes deux appareils: Asus Transformer (10,1 pouces) et HTC Legend (3,2 pouces). Les résultats étaient assez intéressants:

Transformateur (recadré):

Transformer

Et la légende:

Legend

3
howettl

pt Points - 1/72 de pouce basé sur la taille physique de l'écran.

dp Pixels indépendants de la densité - une unité abstraite basée sur la densité physique de l'écran. Ces unités sont relatives à un écran de 160 dpi, donc un dp est un pixel sur un écran de 160 dpi. Le rapport dp/pixel changera avec la densité de l'écran, mais pas nécessairement en proportion directe. Remarque: Le compilateur accepte à la fois "dip" et "dp", bien que "dp" soit plus cohérent avec "sp".

3
Subayan

J'ai eu du mal avec les dimensions, mais je pense avoir trouvé une façon de voir les choses qui me semble logique. Il y a une formule de conversion dans "Beginning Android 4 Application Development" de Wei-Meng Lee: (pg 111):

Pixels réels = dp * (dpi/160), où dpi est soit 120, 160, 240 ou 320

Donc, en utilisant cette formule, je peux trouver le dpi de mon téléphone/émulateur le plus proche de l'une de ces quatre valeurs et cela déterminera le rapport (3/4, 1, 3/2 ou 2) utilisé dans la formule à convertir dp en pixels. Il est important pour moi que le dpi dans la formule ne puisse prendre qu'une de ces quatre valeurs malgré la densité de pixels réelle de l'appareil.

En référence à: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density , pour un Nexus S avec une densité de pixels de 235 dpi, la conversion est:

pixels = dp * 3/2

Donc, un bouton 160dp, disons, serait 240px (un peu plus large qu'un pouce avec les 235 dpi de l'appareil)

Pour un HTC Legend, avec une densité de pixels de 181 dpi, la formule est:

pixels = dp * 1

(parce que 181 est le plus proche de 160). Donc, ce bouton 160dp serait 160pixels, ou légèrement inférieur à un pouce sur l'appareil avec sa densité de pixels de 181 dpi.

Cela m'aide à comprendre l'inexactitude de la documentation précédente Android "1 dp sera toujours égal à 1/160in, quelle que soit la densité de l'écran".

Ce sont les deux points principaux que j'essaie de me mettre en tête :)

  1. une plage de densités réelles de pixels de l'appareil (par exemple: 141-199) donnera le même rapport (1) dans la formule de conversion
  2. mais à moins que la densité de pixels d'un appareil particulier ne soit exactement de 160 dpi, le 160 dp ne sera pas un pouce sur l'appareil ... fermer au-dessus ou en dessous, mais pas exactement
3
gcbound

Pourquoi devrais-je utiliser dp si je peux utiliser pt?

Les développeurs ont l'habitude de penser les choses en termes de pixels. Les pixels indépendants de la densité étaient la façon dont Android se rapprochait de ce à quoi les développeurs sont habitués. Cela étant dit, vous pouvez utiliser des points, des pouces ou des millimètres si vous préférez.

2
CommonsWare

1 dp sera toujours égal à 1/160 in, quelle que soit la densité de l'écran.

Ce n'est pas vrai comme le montre votre candidature ... D'accord?

BR STeN

0
STeN