Oct 19th, 2016 - written by Kimserey with .
I’ve been playing with Xamarin Android for a while now and one thing that disturbed me when I started was the units of measure. What is the difference between DP, DPI, PPI and PX in Android? I found my answers in the Material design guide and today I would like to share my undertanding of the differences and bring a different explanation which hopefully will help you get a better understanding.
Pixels is the most granular unit of measure. When talking about resolution 1920x1080, 2560x1440, etc.. It represents the amount of pixels which fit in the screen.
The higher the better but a second aspect equally important has too be taken in consideration - the screen dimension.
Two devices with the same resolution but different screen sizes will not have the same display. For a similar resolution, the bigger the screen, the bigger the pixel size will be - it would be as if we stretch the screen which makes each pixels look bigger.
To take the screen dimension into account, another measure was created - DPI or PPI - density per pixel also called pixel per inch.
DPI and PPI represent the same thing except - pixel per inch. This unit helps to measure the size of a pixel. It is an indicative of how many pixels can be found in one inch.
So the higher the density, the more pixels can be pushed into one inch.
How does density affect the display?
If we were to construct elements using pixels, the elements will appear smaller on high density devices - because many pixels are available per inch - and larger on low density devices - because not a lot of pixels are available per inch.
If we had to cater for that in the code of the Android app, it would be a nightmare so that’s where DP - density-independent pixel - came from.
DP is the density-independent pixel unit. Independent pixel because the unit of measure is independent of the density, it is independent of the screen dimension and resolution. Whether the density is high or low, the elements on the screen will have approximatively the same size/look.
This is very important for measures of margins and paddings as we want margins and paddings to always be consistant.
But how does it work? How is the unit independent of the screen density?
In order to create a unit of measure independent of the density, Android has defined multiple buckets - mdpi / hdpi / xhdpi / xxhdpi / xxxhdpi.
Each buckets represent a certain amount of DPI and have been given a label ranging from mdpi - the lowest resolution with the lowest density - up to xxxhdpi - the highest resolution with the highest density.
For each of this buckets, a ratio has been attributed. Starting from mdpi ratio of 1.0 up to xxxhdpi ratio of 4.0. As you might have guessed, all dpis have been normalized to mdpi, in order words 1 px in mdpi is equivalent to 4 pixel in xxxhdpi. And this is the key behind DP, so let me repeat it, 1 px in mdpi is equivalent to 4 pixel in xxxhdpi.
The formula behind it is the following:
px = (screen dpi / 160) * dp
px = dp * (dpi/160)
px = dp * ratio
The formula says that
to calculate the pixels, normalize the screen density (dpi/160) and time the density-independent pixels.
Obviously you can move the variables around and get the dp in function of the px.
dp = (px * 160) / dpi
The DPI being a variable constant to the device and 160 being the normal, the whole
160/dpi can then become a constant:
with K = 160 / dpi
dp = px * K
And that’s where DP came from, DP is PX time a constant K which varies depending on the screen density and ensure a consistant measure accross any screen and resolution.
By using that we can have a unit of measure consitant accross all density where
1 dp in
mdpi is equal to
1 dp in
xhdpi or in
xxxhdpi and at the moment of translating
px, the formula is applied where
px = dp * ratio.
Today we saw where the unit DP came from. It is important to understand especially when you start dealing with drawings and canvas. Understanding this took me a while and I hope that I made the task easier for you. Let me know what you think by leaving a comment below or hit me on Twitter @Kimserey_Lam. See you next time!