I learned that we should use "dp" to give our applications the ability of supporting multiple screens. But I find in reality, this works far from well.
Let me show you an example: Assume we have two screens. Screen A has a resolution of 160 * 160 px and 1 inch length and width. Screen B has a resolution of 1600 * 1600 px and 10 inches length and width. According to the definition of Density Buckets, both of the two screens fall into mdpi(medium)~160dpi. So both of the phones using these screens will use the same layouts and drawables. However, we know that 1 dp could be converted to 1px in the case of 160dpi. So this means screen A is 160dp in width and screen B is 1600dp in width. And if we try to show an image which is set to 300 dp in width in the screen, the result is for sure very different. So I am wondering how come android rely on dp to support multiple screens or If I have some misunderstandings about this concept?
Related
I searched a lot about dp, px, inch, pt etc.
From what I understood about 'dp':
Specifying 'dp' is simply a way to make Android draw the views with same size for devices with different screen densities. Eg, for a medium density device, each 'dp' will occupy a pixel. For a high density device - which has smaller pixels to fit more pixels per inch, 'dp' will occupy more than a pixel. For a low density device - which has larger pixels to fit less pixels per inch, 'dp' will occupy less than a pixel.
But what I also read is that space occupied by a 'dp' varies according to screen sizes, i.e for a small screen a 'dp' will occupy less space, while for a larger screen a 'dp' will occupy larger space.
How exactly does this happen? From what I understood about 'dp', it should occupy the same amount of space in devices with differing screen sizes. Eg, a large screen of 240 dpi will have a 'dp' occupy 1.5 pixels, and so will be the case for a small screen of 240 dpi. Then how is it that a 'dp' will occupy different amount of space for different screen sizes?
What am I missing in my understanding of 'dp'? Please help.
Android defines a baseline dpi of 160 which is used as the reference to compute sizes for all screen densities:
pixel_size * (device_dpi / baseline_dpi) = result in "dp" units
>> or the other way around
dp_size / (device_dpi / baseline_dpi) = result in "pixel" units
Therefore, 1 pixel in a 240dpi device is equivalent to 1.5dp units:
1 * (240 / 160) = 1.5
and the other way around, 1.5dp units in a 240dpi device is equivalent to 1 pixel
1.5 / (240 / 160) = 1
The important fact to know is that 160 is the baseline used as the reference for all DPIs.
So, as dp units increase/decrease, the required pixels area to draw something translates into keeping the same size scale regardless of the device screen.
More information in the official documentation.
To be more clear:
The display size is not related to "dp units". The display size is just how big the display canvas is. The screen DPI defines how many dots fit in 1 square inch. And a "dp unit" is an abstract unit that, depending on the device's DPI, is scaled (up or down) to give "uniform dimensions" on any screen size, by using 160 as the baseline reference.
on the Android operating system a device-independent pixel is equivalent to one physical pixel on a 160 dpi screen. By this definition, you can understanddp has no relation with screen sizes as the scale is already fixed as 160 dpi.
.
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.
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.
One would say that if the Galaxy Tab screen resolution (in portrait mode) is 600px and the screen width is 3.55inch, the screen density would be 600/3.55 = 169 dpi. Knowing that and keeping in mind the way the device independent pixels (dp) is computed (http://developer.android.com/guide/practices/screens_support.html):
px = dp * (dpi / 160);
600 = dp * (169 / 160);
dip = 568
So drawing a horizontal line of 568dp (device independent pixels) width starting at position 0 must exactly match the width of the screen. But if you try this on device you will find that the screen width is 400dp. I will use the same formula again but for getting dpi:
600 = 400 * (dpi / 160);
dpi = 240
So having the 240dpi, 3.55inch screen width and 600pixels, does it mean that one physical pixel is composed of more ‘dots’ otherwise the parameters corresponds to the width of 852pixel (3.55*240).
I thought that dpi means dots per inch, which is pixels per inch. But this seems to not be true...
Added later:
This (http://developer.android.com/guide/topics/resources/more-resources.html#Dimension) says:
160dp is always one inch regardless of the screen density
Which is not true. Just check the measurement source from this:
Difference between android dimension: pt and dp
Added even later:
The reason I am asking is that violating the rule that 160dp = 1inch leads to the fact that when specifying the control width to e.g. 320dp it will cover on Galaxy Tab much bigger portion that that really necessary and much bigger then what you would expect from 600x1024px screen...
Thanks for clarification
BR
STeN
Galaxy Tab (7") doesn't report its real density. To understand this issue, read the following article:
http://realmike.org/blog/2010/12/21/multiple-screen-sizes-with-processing-for-android/
Apparently, that’s also what Samsung found when they made the Galaxy
Tab. The Galaxy Tab has a 7″, 1024×600 screen with 170 dpi. Yet, the
Tab does not report its density as “mdpi” but as “hdpi”, so the layout
looks exactly as in the second screenshot. If they used “mdpi”, the
icons would be .28″ wide, with “hdpi”, they are .42″ wide—not a big
deal, and I must admit, the layout does look prettier this way.
The article contains some images that will make you understand the problem.
im throughoutly confused by dips on Android.
I understand from the reference that the base for dp values is 160.
So, shouldn't 80dp in width equals a view with a width of 50% of the screen ?
On my Nexus One the width in dp is something around 300dp as it seems.
What am i missing here ?
thx in advance
"dp" == "Density-independent Pixels" (This is also why it was earlier called "dip", though I prefer to use "dp" these days.)
Think of it like other units -- "in" (inches), "mm" (millimeters), etc. It allows you to provide a size that is scaled based on the density of the screen.
We define mdpi to be the base density, so "10dp" on an mdpi screen will result in exactly 10 pixels. On an hdpi screen it will result in 15 pixels, because hdpi is 1.5*mdpi.
Note that though the constants for various densities are similar to DPI (mdpi is 160, etc), density is not exactly DPI. It is an abstract scaling factor that adjusts for screen dpi, but does not try to exactly reflect it. (You would use "in", "mm", etc for exact sizes but 99.9% that is not what you want so stick with "dp".) This greatly simplifies life for everyone because you don't need to deal with many Android devices having a slightly different amount of space for its UI because they each of slight different screen DPIs. Also, device manufacturers can select the density of their device to achieve a desired UI -- for example the Samsung Tab uses a density that is a fair amount larger than the actual DPI, resulting in an overall larger UI.
160 dots per inch. So 80dp would be 1/2 an inch, roughly.
I don't understand your question completely but I suggest you take a look at this, if you haven't already.
http://developer.android.com/guide/practices/screens_support.html
pixels = dps * (density / 160)
Density independent pixels (short: dp) are a virtual pixel unit that will be determined at the runtime of your application.
Formala:
1 dp = 1 Pixel on 160 dpi screen.
So 160 dpi is the baseline density for the system.
The conversion of dp units to screen pixels are quite simple.
Actual device pixels (px) = dp (1) * (dpi (of the device) / 160(baseline) )
For the sake of simplicity: px = dp * (dpi / 160)
Example:
If a 240 dpi device starts your app, then 1 dp equals to 1,5 actual device pixels.
Conclusion:
Dp automatically handles any scaling to bigger or smaller devices. The times where you hardcode the pixels are over. DP ensures the proper scaling on different screen densities.