Difference between android dimension: pt and dp
The documentation says that 160 dp (density-independent) equals 1 inch. And 72 pt is also 1 inch. So I don't see why android define a dp measurement while it seems to work the same as points. Can anybody explain that? Why should I use dp if I can use pt?
The Android documentation used to incorrectly state that 160 dp always equals 1 inch regardless of screen density. This was reported as a bug which was accepted and the documentation updated.
From the updated documentation:
160 dp will NOT always equal 1 inch, it will vary with different screen sizes and densities. On a screen with a density of 160dpi (mdpi), 160 dp will equal 1 inches.
1 pt will always equal 1/72 in, regardless of the screen density.
The Android documentation for this is here.
UPDATE:
I made a small application to try and verify the different sizes. It looks like what is above is correct, at least when shown on my HTC Aria. Here is a screenshot:
It's interesting to note that these sizes did NOT match up exactly in the eclipse graphical editor. The dp and sp sizes wavered depending on the size of the screen and resolution in the editor. Here are some screenshots from the editor (left is 2.7in QVGA slider, right is 10.1in WXGA, clipped):
It would be interesting to see if these editor renders match up with the actual devices. Can anyone verify these sizes? I'll attach my xml below in case anyone wants to help out.
<?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: Added 2 more devices to John's example. On the left a Samsung Nexus S (OS 2.3.3). On the right, a Samsung Galaxy Tab 10.1 (OS 3.1). No mods.
On the Nexus S, 160dp is slightly larger than 1 inch. All the normal physical units (in, mm, pt) are all the same size. I measured it with a ruler, and the 160 dp bar is about 1mm larger than it should. While the physical units are 1mm shorter than they should.
On the Tab, all bars are exactly the same, and 1mm longer than what I measured with a ruler.
The documentation says that 160 dp (density-independent) equals 1 inch. And 72 pt is also 1 inch.
The nuance here is that 160 dp
(or dip
) is roughly 1 inch, while 72 pt
is exactly 1 inch. The difference is how android converts both units to pixels, which depends on the screen density of the device.
A single dp
is a single px
on a device at 160 dpi. Android uses the "density bucket" the device falls into, and multiplies a scaler to convert dp
to 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
to px
converts following this formula: dp * scaler = px
.
A single pt
is exactly 1/72 of an inch on any screen density. Android converts pt
to px
using the exact dpi (xdpi and ydpi) of the device's screen.
pt
to px
converts following this formula: pt / 72 * dpi = px
.
So I don't see why android define a dp measurement while it seems to work the same as points. Can anybody explain that? Why should I use dp if I can use pt?
Take an example, display 160 dp
and 72 pt
on a 160 dpi device. A 160 dpi device falls into the mdpi density bucket, with a scaler of 1.0. Use the formulas above to convert to px
.
160 dp * 1.0 = 160 px
72 pt / 72 * 160 = 160 px
What about on a 170 dpi device? A 170 dpi device falls into the mdpi density bucket, with a scaler of 1.0.
160 dp * 1.0 = 160 px
72 pt / 72 * 170 = 170 px
What about on a 150 dpi device? A 150 dpi device falls into the mdpi density bucket, with a scaler of 1.0.
160 dp * 1.0 = 160 px
72 pt / 72 * 150 = 150 px
The moral of the story is, dp
keeps exact dimensions and helps keep performance, allowing some physical size variation depending on device density. On the other hand, pt
is exactly the same physical size on every density, which leads to a different amount of px
being used, which can hinder performance and cause aliasing and artifacts if used on images. dp
is recommended unless absolutely exact physical dimensions are required (you have a ruler on screen, etc).
I have written an in depth blog on Android's dimension units, which gives more info and sample code - Understanding Density Independence in Android
Out of curiosity, I tried the layout from John's answer on my two devices: Asus Transformer (10.1 in) and HTC Legend (3.2 in). The results were pretty interesting:
Transformer (cropped):
And Legend: