Why was dp created when there were already other density independent units such as cm?
Is the dp to px conversion by the Android system based on buckets rather than the exact device's pixel density? Wouldn't this result in a discrepancy in how much physical space elements measure on different device screens?
Because cm are too big. You'd have to work with floats, which means you'd need to round all the time. They wanted something smaller. Also, the first devices were 160 dpi, do 1dp=1px which was convenient at the time (now very few devices ship at mdpi so this advantage is gone). It also just so happens to match the dpi of the iphone, rounded to the nearest 10 (iphone was 163 dpi), so measurements were what mobile devs were used to making easy conversions.
Its based on the physical dimensions. There can be some discrepancy, but in practice there isn't. If you have an image that is a little too small, the amount of distortion you get from stretching the tiny amount is negligible. The other major use of dp is in padding, and there the slight rounding errors are unnoticable as long as you're consistent on a single device.
As said by #Gabe Sechan, cm are too big (even mm). Contrary to cm, conversion to pixels is based on density category rather than exact density of the screen, which avoids rounding issues you'd have with cm to px (factor of 1.5x, 2x, 3x, etc rounds much better than an "arbitrary" ppi).
Yes. Conversion of dp to px is based on the density bucket the screen belongs to (mdpi, hdpi, xhdpi, etc) rather than the exact physical ppi. Bitmap graphics of an app are categorized by buckets, so for measurement consistency the dp is converted based on the density bucket rather than the real ppi. The drawback is that unlike a unit such as cm, the measurements are not guaranteed to be the same physical size on every screen (example of such inconsistency).
References:
Why aren't standard physical length units like mm used for touch UI layout?
Why “dp-to-pixel” ratio changes with the screen density, but not necessarily in direct proportion
Related
I'm asking this question after much reading. I've always heard that dpi is for printers, but when it comes to screen now, they are also talking about dpi. Are they referring to ppi?
Now, what is really resolution, for me its the the number of pixels each dimension can display, e.g. 800x600 means 800 pixesl on width and 600 pixels on the height, but at some places I'm seeing that they are referring to resolution as dpi.
I'm trying to understand this concept well because its very important in Android, like in this article,
For example, say an icon is intended to be 0.5x0.5 in when rendered on a screen. Next, the image must be created at the largest density supported, or as a scalable vector graphic. Best practice is to support the maximum density, which currently is xxhdpi at 480 dpi. At 480 dpi, a 0.5x0.5 in image converts to 240x240 px.
So it is referring dpi as ppi actually if I understand?
So far what I've understood is that different pixels may render different number of pixels. This is why we don't use pixels as measurement unit. Instead we use dp, where a dp is one pixel on 160 dpi device (again the confusion about dpi & ppi)
Can someone clear this big confusion or direct me to an article that may clear it
Mate, Resolution being 800 X 600 implies that the screen has 480,000 pixel points that will be used to render the screen(This is often confused with the dimensions of the display). DPI or PPI means dots/points per inch, this is the measure of the density of the screen.
So just given the Resolution, one can not determine the actual length of the display unless the density parameter is also available. So a 800 X 600 resolution has 480,000 Pixel points & a let this device has a density of 480 dpi.
So the Width of the screen
= No of pixel points along its width/Density
= 800/480
= 1.67 inches
Similarly,
Height = 600/480
=1.25 inches
and if 800X600 resolution device has density of 160 dpi, its dimensions will vary drastically. Following calculations calculate Height/Width of 800X600 on 160 dpi. Compare these two values with above 480 dpi calculations.
the Width of the screen
= No of pixel points along its width/Density
= 800/160
= 5.0 inches
Similarly,
Height = 600/160
=3.75 inches
This is the very reason that scaling images to best fit the screen is such a complex issue on frafmented android environment.However, I love android!
Hope this helps!
and any one who has some thing to add/delete.modify to this answer is most welcome.
dpi (dots per inch) == ppi (pixels per inch)
You are also talking about the DisplayMetrics.density, which gives you the multiplier for the dp unit of measurement.
There's also DisplayMetrics.scaledDensity which also takes into account text size user chose.
To put it plainly, dp unit is intended to give you some security about size of your objects on screen. 160dp should represent one inch on any screen. In order to achieve that, you have to multiply your dimension by DisplayMetrics.density or DisplayMetrics.scaledDensity.
That is, if you're doing that in code. For Layouts, you can just enter a View's dimensions in dp and have Android framework take care of that for you.
There are a lot of questions on this on here, but none that answer my specific question. When I use px, eclipse tells me to avoid it. So I did. But when I use dp, the grid/borders I am making around my cells in GridView seems too fat. I want it much thinner. When using 1 px as opposed to 1dp, I get the desired result. I understand warning on avoiding it, but should I really avoid it in this case?
Yes you should. "dp" will give pretty the same look on all devices, but pixels are not.
http://developer.android.com/guide/practices/screens_support.html
Long story short:
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
px doesnt work on all devices i think it stopped working in android 2.2
I recommend sticking with dp.
I am a bit worried by what I read here, which kind-of implies that there is no reliable formula to compute px based on dp and screen density (and vice versa):
dp :
Density-independent Pixels - An abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi (dots per inch) screen, on which 1dp is roughly equal to 1px. When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Using dp units (instead of px units) is a simple solution to making the view dimensions in your layout resize properly for different screen densities. In other words, it provides consistency for the real-world sizes of your UI elements across different devices.
I thought we could always use the following formula (explained here) :
px = dp * (dpi / 160)
However, the testimony in this question seems to highlight a case where specifying sizes in dp does not guarantee a fixed perceived size across devices.
What is the real meaning of the sentence in bold ?
Do we need to use mm in order to be sure to keep the same perceived size ??
I thought we could always use the following formula (explained here) : px = dp * (dpi / 160)
This formula can always be used to convert between pixels and dp. Just make sure you use DisplayMetrics.densityDpi as the value for dpi in the formula.
However, the testimony in this question seems to highlight a case where specifying sizes in dp does not guarantee a fixed perceived size across devices.
Yes it is true that a certain dp does not guarantee a fixed perceived size across devices. It does however guarantee a similar perceived size across devices. The reason for this is that on some devices densityDpi (the density bucket) is different than the physical dpi of the device. Please see my answer to the question you linked for more details.
The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion
Here I think they mean the actual physical screen density when they say "screen density" and not which density bucket the phone belongs to.
For example a device with a physical dpi of 270 will belong to the "high" (240) density bucket and have a dp-to-pixel ratio of 240/160 = 1.5
Another device with a physical dpi of 290 will belong to the "xhigh" (320) density bucket and have a dp-to-pixel ratio of 320/160 = 2
When you compare these devices with each other the physical screen density has increased by 7% (270 -> 290) while the dp-to-pixel ratio has increased by 33% (1.5 -> 2) so it's not a direct proportion between them.
Do we need to use mm in order to be sure to keep the same perceived size ??
If it's important that the preceived size is as similar as possible between devices you have to use mm or inch. However this have some drawbacks as I mention in the question you linked.
It is also important to keep in mind that there are some devices where the mm and inch units are broken, for more information on this see the question Why Lint shows warning when using in (inch) or mm (millimeter) units as dimension?
72 pts is always equal to 1 inch, yet 160 dip is not always equal to 1 inch.
As such, why do people recommend us to use dips instead of pts?
Isn't it better to base our dimensions on pts which is predictable, instead of dips which is unpredictable?
The reason why you should use dip (Density Indepentdent Pixel) is that this way your application will support multiple screen sizes. This means that if you set a value to 100dip, it would be translated into 75px on a low density screen (ldpi), 100px on a medium density screen (mdpi), 150px on a high density screen (hdpi) and 200px on a extra high density screen (xhdpi) but the layout will look the same on each screen (but scaled to the screen density).
The only reason to use pt is if you actually need the exact size and don't care about the screen density (I can't see when that would be the case).
You should read through this article to better understand why dp/dip is the way to go:
Supporting Multiple Screens
Also this similar question has a good explenation of the difference between the different units:
Difference of px, dp, dip and sp in android
Always use dip (Device Independent Pixel), this will respect the width and height of the device you're running on. So by using dip, the layout will be the same for all devices.
if you want your app to work in just a single device or a single resolution, you can use pts. if you would like your app to work on multiple resolutions (which i think you would) you are better going with dip or dp. Try your app on different resolutions using the emulator and you would see what the issues are. The app will look different in different resolutions.
Received an email from my first Motorola Droid user. The new 480x854 resolution introduced in Android 2.0 (as opposed to 320x480) is wreaking havoc with my user interfaces. Everything is smaller and ill-positioned.
I was under the impression that if we follow the XML layout guides we were resolution-safe, as no absolute coordinates are used. Does anyone have experience in making the UI resolution-safe? Will we need a main.xml for each resolution times each orientation?
Which dimension units did you use?
AFAIK using dp and sp should keep you safe.
From documentation:
dp
Density-independent Pixels - an abstract unit that is based on the
physical density of the screen. These
units are relative to a 160 dpi
screen, so one dp is one pixel on a
160 dpi screen. The ratio of
dp-to-pixel will change with the
screen density, but not necessarily in
direct proportion. Note: The compiler
accepts both "dip" and "dp", though
"dp" is more consistent with "sp".
sp
Scale-independent Pixels - this is like the dp unit, but it is also
scaled by the user's font size
preference. It is recommend you use
this unit when specifying font sizes,
so they will be adjusted for both the
screen density and user's preference.
The eclair emulator works wonders for these issues, also make sure to read:
http://developer.android.com/guide/practices/screens_support.html
Your application responds to different resolutions based on many factors, even the min-sdk.
Also, from the page, are some best practices:
Prefer wrap_content, fill_parent and the dip unit to px in XML layout files
Avoid AbsoluteLayout
Do not use hard coded pixel values in your code
Use density and/or resolution specific resources
Aside from the resolution difference, the other thing to consider is that the Droid's WVGA screen has a different aspect ratio from previous devices like the G1. In many older apps that I've downloaded, this manifests as a gap at the bottom of the screen, or elements that are vertically misaligned in portrait mode. You may want to try running your app in the emulator with a WVGA skin to check for any hidden assumptions that your layout makes about the aspect ratio.