How to correctly decide pixel dimension of the mdpi baseline drawable according to the dp size? - android

I have investigated and read all the official Android documentation according to the topic of supporting different screen sizes to create different images sizes to support different screen densities. I have not found how to determine the accurate px size of an image of the baseline mdpi density.
I have found this old post of the forum which describes exactly my doubt:
How do you decide the pixel dimensions of your baseline drawable for Android?
That posts has an answer that is interesting but not really clear:
https://stackoverflow.com/a/8073233
In short words this answer says the following:
If you have a (50 x 40)dp image item (like a Button or ImageView), for the mdpi density you shouldn't create the exact pixels (50 x 40)px but you should create a larger image to be divisible by 5 and 4 (as the W:H ratio is 5:4), so for example for a (50 x 40)dp, you should create for mdpi density a (60 x 48 px) so that when it is multiplied by 0.75 for ldpi purposes give exect values (45 x 36 px).
Okay, so now my question is, how could I know how much "larger" should I make the image dimensions in px for the mdpi density (base density) if I have an image item of (X x Y) dp ? Should I make it 10px larger as the case?(Surely not) Or should I make it larger until the other densities in px give exact values? I would like to see a clear explanation of how to get that larger px dimensions of the mdpi density if I have an image item whose width and height is X and Y dp.

Related

Best quality image allocation from resources based on resolution/density

I'm struggling with a pretty trivial task in the Android "multiple-screen sizes" domain.
What I'm trying to achieve
A layout matching the screen width, with a nine-patch background which resizes (only horizontally, since there is always enough vertical space). Here is a dummy image:
My goal is, depending on the screen resolution, to display the image at the highest resolution possible, by using a set of different sizes, eg. 320x45, 480x67, 600x87, 720x101, without any down-scaling. I'm hoping for a non-programmatic solution.
An example with the above mentioned image sizes would be:
3.7" Nexus One (480 x 800) - the 480x67 image would look best.
4.7" Galaxy Nexus (720 x 1280) - the 720x101 image.
4.7" Nexus 4 (768 x 1280) - again the 720x101 image, stretching to the full 768 px width and becoming 768x101.
Issue
The whole Android resource allocation revolves around dps (density-independent pixels), when in fact I want to display an image based on the actual available pixels.
If I allocate the 480x67 image to res/drawable-mdpi and a 600x87 to res/drawable-hdpi, then image would display correctly on a 5.4" display of 480x800, i.e. mdpi display. However, a 4" 480x800 displays qualifies as hdpi and the system would appoint the 600x87 image, which won't fit the screen.
I tried the smallestWidth parameter as described in the online guide, but that yields strange results. For instance, a 3.7" 480 x 800 display (hdpi) uses my drawable-sw320dp image, although there is a drawable-sw480dp resource available too.
What is the best way to assign a stretchable, width-matching image with the best possible quality? Isn't there any non-programmatic solution?
Thanks in advance!
I believe that by combining density and screen size resource qualifiers you can achieve a close to optimal behavior.
Lets assume this kind of resource folders structure:
drawable-normal-hdpi - A normal size dictates minimum width of
320dp. hdpi dictates 1.5X dp to pixel multiplier. So the minimum px
width of the normal hdpi bucket is 480px. We put here a 480px wide
image.
drawable-normal-xhdpi - Again size dictates 320dp but this time
with 2X multiplier. So we use a 640px wide image.
drawable-xlarge-mdpi - Size means at least 720dp. mdpi multiplier
is 1X, so we use a 720px wide image.
Now lets look at some devices to see how they fall in with those buckets:
Nexus one - normal hdpi. Actual px width: 480px. The image fits
perfectly.
Galaxy nexus - normal xhdpi. We could fit a 720px image, so the
640px image we use isn't optimal - but it's very close.
Nexus 4 is just like the Gnex.
Nexus 10.1 (1280X800) - xlarge mdpi. We could fit 800px, our image
is 720px. Again not ideal but close enough.
Worst case scenario: image used could have 5-10% better quality.
Best case: perfect fit.
The main down side of this method is that you need to provide a lot of resources and folders to account for all the permutations of sizes and densities (even worse if you need to combine that with more qualifiers for locale, orientation and so on). However, as far as my Android understanding goes I don't think you can achieve something better than this without coding.
A remark regarding smallestWidth: Your example for the weird behavior is actually the expected behavior.
hdpi multiplier is 1.5 - So a 480px wide hdpi display is exactly 320dp wide. This makes the drawable-sw320dp the right choice, as documented. I'm not sure if you can combine the smallestWidth qualifier with the dpi qualifier. If it's possible you might get more accurate results than just size modifiers. But this would mean a lot more permutations for a 5% increase in image quality. Probably not worth it.
Actually, your method is not how it is supposed to be. I will suggest 2 ways for you, one is easy but doing programmatically, other one is using a custom view.
Method 1 - Programmatically
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
// this will determine "scale ratio" so using which image height and width won't matter
int imageOriginalHeight = 101; // your original image height
int imageOriginalWidth = 720; // your original image width
int imageScaleHeight = (screenWidth*imageOriginalHeight) / imageOriginalWidth;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, imageScaleHeight);
imageView.setLayoutParams(params);
imageView.setImageResource(R.drawable.file);
Method 2 - Custom View
You can use a custom view called ScaleImageView which is written by Maurycy Wojtowicz.
Class is defined like below:
This view will auto determine the width or height by determining if
the height or width is set(exact size or match_parent) and scale the
other dimension depending on the images dimension This view also
contains an ImageChangeListener which calls changed(boolean isEmpty)
once a change has been made to the ImageView
Here is how you are going to implement it.
Create a class named ScaleImageView.java and copy contents of the link above.
In your xml file, create a ScaleImageView, just same like ImageView (the example I am writing below is for filling screenwidth, and scaling height according to that so there will be no empty spaces on right/left)
<com.project.customview.ScaleImageView
android:id="#+id/scaleImageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/file" />
If you need to declare and set programmatically in your Activity, it is also the same as using ImageView:
imageView = (ScaleImageView)findViewById(R.id.scaleImageView);
imageView.setImageResource(R.drawable.file);
In android you have the option hdpi, mdpi, xdpi,etc..
folders for that , you have to create different images according your device resolution and put your images at there after confirming your device resolution and density category.
for the more reference why it'll happen you can see here
here i explain some chart may be helpful to you.
Low density Small screens QVGA 240x320 (120dpi):
drawable-small-ldpi (240x320)
drawable-small-land-ldpi (320x240)
Low density Normal screens WVGA400 240x400 (x432) (120dpi):
drawable-ldpi (240 x 400 )
drawable-land-ldpi (400 x 240 )
Medium density Normal screens HVGA 320x480 (160dpi):
drawable-mdpi (320 x 480 )
drawable-land-mdpi (480 x 320 )
Medium density Large screens HVGA 320x480 (160dpi):
drawable-large-mdpi (320 x 480 )
drawable-large-land-mdpi (480 x 320)
Galaxy Tab ( 240 dpi ):
drawable-large (600 x 1024)
drawable-large-land (1024 x 600)
High density Normal screens WVGA800 480x800 (x854) (240 dpi):
drawable-hdpi (480 x 800)
drawable-land-hdpi (800 x 480)
Xoom (medium density large but 1280x800 res) (160 dpi):
drawable-xlarge (800 x 1280)
drawable-xlarge-land (1280 x 800)

Confusion about Resolution, Screen aspects in Android

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.

Android different drawable screen resolutions

I'm a bit confused as to what resolutions I should be saving my images in for the different drawable folders. Is there a general formula for it? For example,if I want an image to take up 10% of the height and the full width of the screen, roughly how would I calculate what different resolutions I should save the image in?
This is android's guidelines for icons. Obviously not all drawables are icons, but maybe this helps you get started.
36x36 for low-density
48x48 for medium-density
72x72 for high-density
96x96 for extra high-density
From here: http://developer.android.com/guide/practices/screens_support.html
According to android documentation here
http://developer.android.com/guide/practices/screens_support.html#range
In mdpi (baseline density) 1px = 1dp
and under topic 'Range of screens supported' least resolution for a normal size screen(baseline size) in dp is
470dp X 320dp and since in baseline density 1px = 1dp so baseline screen size in pixels would be
470px X 320px
now for baseline screen size and density 10% of 470px would be 47px and full width is 320px so your baseline drawable will have the following size in pixels
47px X 320px
The scaling ratios for alternative drawables is 3:4:6:8 for ldpi:mdpi:hdpi:xhdpi
this means that the above baseline resolution of your graphic is at scale 4. Now to get resolutions for your graphic in other densities we need to divide the mdpi graphic resolution with 4 to get the unit values
height unit = 47/4 = 11.75
width unit = 320/4 = 80
now reoultions in other densities can be calculated by multiplying unit values with respective scaling ratios
ldpi
11.75 X 3 = 35.25px
80 X 3 = 240px
mdpi (already calculated above, doing it again here for clarity)
11.75 X 4 = 47px
80 X 4 = 320px
hdpi
11.75 X 6 = 70.5px
80 X 6 = 480px
xhdpi
11.75 X 8 = 94px
80 X 8 = 640px
There are different guidelines on Android developer site about how to manage the image size and resolution to support multiple screens.
Refer this How to develop one android application for different screens?

Minimum size of background image in Android app

I want to keep an image in the res/drawable folder, which would be used as the background in my app. I wish that my app should work across all devices of varying densities. What minimum size in pixels should the image be kept to maintain balance between a reasonable app size and also supporting multiple screens.
The developer guide mentions that:
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
I use Photoshop where the images are always in pixels and not dp and hence the confusion. By the way, I am quite new at Android as well as Photoshop.
If you want to convert dp values to pixels u can use following formula:
int px = (int) (dp * logicalDensity + 0.5);
To get dp from pixels, divide the density into the pixel value rather than multiply.
Try to study about 9-patch image. This single image could solve your issue.
You have to create images 320x480 size save in drawable-mdpi folder and 480x800 size save in drawable-hdpi folder
These both size image run in every small and large screen device.
for medium device 320x480 and for high density 480x800.
Don't use a fixed size image at all. Use a little image as a tiled background or define background as a gradient or whatever using xml resources.
px is one pixel. scale-independent pixels ( sp ) and density-independent pixels ( dip ) you want to use sp for font sizes and dip for everything else. dip==dp from here http://developer.android.com/guide/topics/resources/more-resources.html#Dimension
px
Pixels - corresponds to actual pixels on the screen.
in
Inches - based on the physical size of the screen.
mm
Millimeters - based on the physical size of the screen.
pt
Points - 1/72 of an inch based on the physical size of the screen.
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.

What is the difference between px, dip, dp, and sp?

What is the difference between the units of measure
px, dip, dp, and sp?
From the Android Developer Documentation:
px
Pixels - corresponds to actual pixels on the screen.
in
Inches - based on the physical size of the screen.
1 Inch OR 2.54 centimeters
mm
> Millimeters - based on the physical size of the screen.
pt
> Points - 1/72 of an inch based on the physical size of the screen.
dp or dip
> 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
> Scaleable Pixels OR scale-independent pixels - this is like the dp unit, but it is also scaled by the user's font size preference. It is recommended you
use this unit when specifying font sizes, so they will be adjusted
for both the screen density and the user's preference. Note, the Android documentation is inconsistent on what sp actually stands for, one doc says "scale-independent pixels", the other says "scaleable pixels".
From Understanding Density Independence In Android:
Density Bucket
Screen Density
Physical Size
Pixel Size
ldpi
120 dpi
0.5 x 0.5 in
0.5 in * 120 dpi = 60x60 px
mdpi
160 dpi
0.5 x 0.5 in
0.5 in * 160 dpi = 80x80 px
hdpi
240 dpi
0.5 x 0.5 in
0.5 in * 240 dpi = 120x120 px
xhdpi
320 dpi
0.5 x 0.5 in
0.5 in * 320 dpi = 160x160 px
xxhdpi
480 dpi
0.5 x 0.5 in
0.5 in * 480 dpi = 240x240 px
xxxhdpi
640 dpi
0.5 x 0.5 in
0.5 in * 640 dpi = 320x320 px
Unit
Description
Units Per Physical Inch
Density Independent?
Same Physical Size On Every Screen?
px
Pixels
Varies
No
No
in
Inches
1
Yes
Yes
mm
Millimeters
25.4
Yes
Yes
pt
Points
72
Yes
Yes
dp
Density Independent Pixels
~160
Yes
No
sp
Scale Independent Pixels
~160
Yes
No
More info can be also be found in the Google Design Documentation.
Pretty much everything about this and how to achieve the best support for multiple screens of different sizes and densities is very well documented here:
Supporting Multiple Screens
Screen size
Actual physical size, measured as the screen's diagonal.
For simplicity, Android groups all actual screen sizes into four
generalized sizes: small, normal, large, and extra-large.
Screen density
The number of pixels within a physical area of the
screen; usually referred to as dpi (dots per inch). For example, a
"low" density screen has fewer pixels within a given physical area,
compared to a "normal" or "high" density screen. For simplicity,
Android groups all actual screen densities into six generalized
densities: low, medium, high, extra-high, extra-extra-high, and
extra-extra-extra-high.
OrientationThe orientation of the screen from the user's point of
view. This is either landscape or portrait, meaning that the screen's
aspect ratio is either wide or tall, respectively. Be aware that not
only do different devices operate in different orientations by
default, but the orientation can change at runtime when the user
rotates the device.
Resolution The total number of physical pixels on
a screen. When adding support for multiple screens, applications do
not work directly with resolution; applications should be concerned
only with screen size and density, as specified by the generalized
size and density groups.
Density-independent pixel (dp) A virtual
pixel unit that you should use when defining UI layout, to express
layout dimensions or position in a density-independent way.
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.
If you are at all serious about developing an Android app for more than one type of device, you should have read the screens support development document at least once. In addition to that, it is always a good thing to know the actual number of active devices that have a particular screen configuration.
Screen Sizes and Densities
I will elaborate more on how exactly does dp convert to px:
If running on an mdpi device, a 150 x 150 px image will take up 150 * 150 dp of screen space.
If running on an hdpi device, a 150 x 150 px image will take up 100 * 100 dp of screen space.
If running on an xhdpi device, a 150x150 px image will take up 75 * 75 dp of screen space.
The other way around: say, you want to add an image to your application and you need it to fill a 100 * 100 dp control. You'll need to create different size images for supported screen sizes:
100 * 100 px image for mdpi
150 * 150 px image for hdpi
200 * 200 px image for xhdpi
Moreover you should have a clear understanding of the following concepts:
Screen size:
Actual physical size, measured as the screen's diagonal. For simplicity, Android groups all actual screen sizes into
four generalized sizes: small, normal, large, and extra-large.
Screen density:
The number of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). For example, a
"low" density screen has fewer pixels within a given physical area,
compared to a "normal" or "high" density screen. For simplicity,
Android groups all actual screen densities into four generalized
densities: low, medium, high, and extra high.
Orientation:
The orientation of the screen from the user's point of view. This is either landscape or portrait, meaning that the
screen's aspect ratio is either wide or tall, respectively. Be aware
that not only do different devices operate in different orientations
by default, but the orientation can change at runtime when the user
rotates the device.
Resolution:
The total number of physical pixels on a screen. When adding support for multiple screens, applications do not work directly
with resolution; applications should be concerned only with screen
size and density, as specified by the generalized size and density
groups.
Density-independent pixel (dp):
A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or
position in a density-independent way. 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.
Reference: Android developers site
dp is dip. Use it for everything (margin, padding, etc.).
Use sp for {text-size} only.
To get the same size on different screen densities, Android translates these units into pixels at runtime, so there is no tricky math for you to do.
See the difference between px, dp and sp on different screen sizes.
Source: Android Programming: The Big Nerd Ranch Guide
Definitions
px or dot is a pixel on the physical screen.
dpi are pixels per inch on the physical screen and represent the density of the display.
Android gives alias names to several densities
ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
most devices in 2015 are here
xhdpi (extra-high) ~320dpi
Apple iPhone 4/5/6, Nexus 4
xxhdpi (extra-extra-high) ~480dpi
Nexus 5
xxxhdpi (extra-extra-extra-high) ~640dpi
dip or dp are density-indenpendant pixels, i.e. they correspond to more or less pixels depending on the physical density.
1dp = 1px on mdpi
sp or sip is a scale-independant pixel. They are scaled when the Large Text option is turned on in Settings > Accessibility
1sp = 1dp
1sp = 1.2dp with accessibility Large Text
What to use?
Use sp for Text size.
Use dp for everything else.
I have calculated the formula below to make the conversions dpi to dp and sp
Source 1
Source 2
Source 3: (data from source 3 is given below)
These are dimension values defined in XML. A dimension is specified
with a number followed by a unit of measure. For example: 10px, 2in,
5sp. The following units of measure are supported by Android:
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.
sp
Scale-independent Pixels - This is like the dp unit, but it is also
scaled by the user's font size preference. It is recommended that you use
this unit when specifying font sizes, so they will be adjusted for
both the screen density and the user's preference.
pt
Points - 1/72 of an inch based on the physical size of the screen.
px
Pixels - Corresponds to actual pixels on the screen. This unit of
measure is not recommended because the actual representation can vary
across devices; each device may have a different number of pixels per
inch and may have more or fewer total pixels available on the screen.
mm
Millimeters - Based on the physical size of the screen.
in
Inches - Based on the physical size of the screen.
Note: A dimension is a simple resource that is referenced using the value provided in the name attribute (not the name of the XML file). As such, you can combine dimension resources with other simple resources in one XML file, under one element.
Basically the only time where px applies is one px, and that's if you want exactly one pixel on the screen like in the case of a divider:
On >160 dpi, you may get 2-3 pixels,
On >120 dpi, it rounds to 0.
Where to use what & relationship between px & dp?
Density-independent pixel (dp)
A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way. As described above, 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.
Understanding pixel to dp and vice versa is very essential (especially for giving exact dp values to creative team)
dp = px * 160 / dpi
MDPI = 160 dpi || Therefore, on MDPI 1 px = 1 dp
For example, if you want to convert 20 pixel to dp, use the above formula,
dp = 20 * 160 / 160 = 20.
So, 20 pixel = 20 dp.
HDPI = 240 dpi - So, on HDPI 1.5 px = 1 dp
XHDPI = 320 dpi - So, on XHDPI 2 px = 1 dp
XXHDPI = 480 dpi - So, on XXHDPI 3 px = 1 dp
For example, let us consider Nexus 4.
If 24 pixels to be converted to dp and if it is a Nexus 4 screen, developers can
convert it to dp easily by the following calculation :
dp = 24 * 160 / 320 = 12 dp
Screen dimension:
768 x 1280 pixel resolution (320 ppi or 320dpi)
Optional (screen size):
4.7" diagonal
Try to get all pixel values in even numbers from the creative team. Otherwise precision lose will happen while multiplying with 0.5.
px
It is explained above. Try to avoid in layout files. But there are some cases, where px is required. for example, ListView divider line. px is better here for giving a one-pixel line as a divider for all across screen resolutions.
sp
Use sp for font sizes. Then only the font inside the application will change while device fonts size changes (that is, Display -> Fonts on Device). If you want to keep a static sized font inside the app, you can give the font dimension in dp. In such a case, it will never change. Developers may get such a requirement for some specific screens, for that, developers can use dp instead of sp. In all other cases, sp is recommended.
You can see the difference between px and dp from the below picture, and you can also find that the px and dp could not guarantee the same physical sizes on the different screens.
Anything related with the size of text and appearance must use sp or pt. Whereas, anything related to the size of the controls, the layouts, etc. must be used with dp.
You can use both dp and dip at its places.
I would only use dp.
There is a lot of talk about using "sp" for font sizes, and while I appreciate the point, I don't think that it is the right thing to do from a design point of view. You can end up breaking your design if the user has some wonky font size selection, and the user will end up blaming the app, and not their own life choices.
Also, if you take an sp-font app on a 160 dpi tablet, you will find that everything scales up... but your font, which is going to look tiny in comparison. It isn't a good look.
While the idea of "sp" fonts has a good heart, it is a poor idea. Stick with dp for everything.
sp = scale independent pixel
dp = dip = density independent pixels
dpi = dots per inch
We should avoid to use sp.
We should use dp to support multiple screens.
Android supports different screen resolutions
ldpi (low) ~120 dpi
mdpi (medium) ~160 dpi
hdpi (high) ~240 dpi
xhdpi (extra-high) ~320 dpi
xxhdpi (extra-extra-high) ~480 dpi
xxxhdpi (extra-extra-extra-high) ~640 dpi
An 120 dp ldpi device has 120 pixels in 1 inch size.
The same for other densities...
We as software engineers should use this conversion formula:
pixel = dp * (density / 160)
So 240 dpi device's 1 dp will have = 1 * (240/160) = 3/2 = 1.5 pixels.
And 480 dpi device's 1 dp will have = 1 * (480/160) = 3 pixels.
Using this 1.5 and 3 pixels knowledge, a software engineer can design layouts for different densities.
To check screen parameters of any device:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Toast.makeText(
this,
"4:" + metrics.heightPixels + "," + metrics.density + ","
+ metrics.densityDpi, Toast.LENGTH_LONG).show();
Difference between dp and sp units mentioned as "user's font size preference" by the answers copied from official documentation can be seen at run time by changing Settings->Accessibility->Large Text option.
Large Text option forces text to become 1.3 times bigger.
private static final float LARGE_FONT_SCALE = 1.3f;
This might be well of course vendor dependent since it lies in packages/apps/Settings.
dpi -
Dots per inches
Measuring the pixel density of the screen.
px - pixel
For mapping screen pixels
pt - points
About 1/72 of an inch, with respect to physical screen size.
in - inch
- with respect to physical screen size(1 inch = 2.54 cm).
mm- milimeter
- with respect to physical screen size.
sp - scale-independent pixel.
Based on user`s font size preference.
Font should be in 'sp'.
dip -
dip == dp
Density independent pixel.
It varies based on Screen Density.
In 160 dpi screen, 1 dp = 1 pixel.
Use dp except the text font size.
In standard, dp and sp are used. sp for font size and dp for everything else.
Formula for conversion of units:
px = dp * ( dpi / 160 );
Density Bucket -> Screen Display => Physical Size => Pixel Size
ldpi -> 120 dpi => 0.5 x 0.5 in => 0.5 in * 120 dpi = 60x60 px
mdpi -> 160 dpi => 0.5 x 0.5 in => 0.5 in * 160 dpi = 80x80 px
hdpi -> 240 dpi => 0.5 x 0.5 in => 0.5 in * 240 dpi = 120x120 px
xhdpi -> 320 dpi => 0.5 x 0.5 in => 0.5 in * 320 dpi = 160x160 px
xxhdpi -> 480 dpi => 0.5 x 0.5 in => 0.5 in * 480 dpi = 240x240 px
xxxhdpi -> 640 dpi => 0.5 x 0.5 in => 0.5 in * 640 dpi = 320x320 px
Please read the answer from the community wiki.
Below mentioned is some information to be considered in addition to the above answers. Most Android developers miss this while developing apps, so I am adding these points.
sp = scale independent pixel
dp = density independent pixels
dpi = density pixels
I have gone through the above answers...not finding them exactly correct.
sp for text size, dp for layout bounds - standard.
But sp for text size will break the layout if used carelessly in most of the devices.
sp take the text size of the device, whereas dp take that of device density standard( never change in a device)
Say 100sp text can occupy 80% of the screen or 100% of the screen depending on the font size set in the device
You can use sp for layout bounds also, it will work :)
No standard app use sp for whole text
Use sp and dp for text size considering UX.
Don't use sp for text in the toolbar( can use android dimens available for different screen sizes with dp)
Don't use sp for text in small bounded buttons, very smaller text, etc
Some people use huge FONT size in their phone for more readability, giving them small hardcoded sized text will be a UX issue. Put sp for text where necessary, but make sure it won't break the layout when the user changes his settings.
Similarly, if you have a single app supporting all dimensions, adding xxxhdpi assets increases the app size a lot. But now xxxhdpi phones are common so we have to include xxxhdpi assets at least for icons in the sidebar, toolbar, and bottom bar. It's better to move to vector images to have a uniform and better quality images for all screen sizes.
Also, note that people use custom fonts on their phones. So lack of a font can cause problems regarding spacing and all. Say text size 12sp for a custom font may take some pixels extra than the default font.
Refer to google developer site for screen densities and base density details for android.
https://developer.android.com/training/multiscreen/screendensities
Screen Size in Android is grouped into categories small, medium, large, extra large, double-extra and triple-extra. Screen density is the number of pixels within an area (like an inch) of the screen. Generally, it is measured in dots-per-inch (dpi). Screen density is grouped as low, medium, high, and extra high. Resolution is the total number of pixels on the screen.
dp: Density Independent Pixel, varies based on screen density. In 160 dpi screen, 1 dp = 1 pixel. Except for font size, use dp always.
dip: dip == dp. In earlier Android versions dip was used and later changed to dp.
sp: Scale Independent Pixel, scaled based on user’s font size preference. Fonts should use sp.
px: our usual standard pixel which maps to the screen pixel.
in: inches, concerning the physical screen size.
mm: millimeters, concerning the physical screen size.
pt: 1/72 of an inch, concerning the physical screen size.
Formula for Conversion between Units
px = dp * (dpi / 160)
dp to px in device
The following example may help understand better. The scaling occurs based on bucket sizes of 120(ldpi), 160(mdpi), 240(hdpi), 320(xhdpi), 480(xxhdpi), and 640(xxxhdpi). The Google suggested ratio for designing is 3:4:6:8:12 for ldpi:mdpi:hdpi:xhdpi:xxhdpi
A 150px X 150px image will occupy,
150 dp X 150 dp screen space in mdpi
100 dp X 100 dp screen space in hdpi
75 dp X 75 dp screen space in xhdpi
You may use the following DPI calculator to fix your image sizes and other dimensions when you wish to have a uniform UI design on all Android devices.
DPI Calculator in Java
/*
Program output
LDPI: 165.0 X 60.0
MDPI: 220.0 X 80.0
HDPI: 330.0 X 120.0
XHDPI: 440.0 X 160.0
XXHDPI: 660.0 X 240.0
XXXHDPI: 880.0 X 320.0
*/
public class DPICalculator {
private final float LDPI = 120;
private final float MDPI = 160;
private final float HDPI = 240;
private final float XHDPI = 320;
private final float XXHDPI = 480;
private final float XXXHDPI = 640;
private float forDeviceDensity;
private float width;
private float height;
public DPICalculator(float forDeviceDensity, float width, float height){
this.forDeviceDensity = forDeviceDensity;
this.width = width;
this.height = height;
}
public static void main(String... args) {
DPICalculator dpiCalculator = new DPICalculator(240,330,120);
dpiCalculator.calculateDPI();
}
private float getPx(float dp, float value) {
float px = dp * (value / forDeviceDensity );
return px;
}
private void calculateDPI() {
float ldpiW = getPx(LDPI,width);
float ldpiH = getPx(LDPI,height);
float mdpiW = getPx(MDPI,width);
float mdpiH = getPx(MDPI,height);
float hdpiW = getPx(HDPI,width);
float hdpiH = getPx(HDPI,height);
float xdpiW = getPx(XHDPI,width);
float xdpiH = getPx(XHDPI,height);
float xxdpiW = getPx(XXHDPI,width);
float xxdpiH = getPx(XXHDPI,height);
float xxxdpiW = getPx(XXXHDPI,width);
float xxxdpiH = getPx(XXXHDPI,height);
System.out.println("LDPI: " + ldpiW + " X " + ldpiH);
System.out.println("MDPI: " + mdpiW + " X " + mdpiH);
System.out.println("HDPI: " + hdpiW + " X " + hdpiH);
System.out.println("XHDPI: " + xdpiW + " X " + xdpiH);
System.out.println("XXHDPI: " + xxdpiW + " X " + xxdpiH);
System.out.println("XXXHDPI: " + xxxdpiW + " X " + xxxdpiH);
}
}
More Information refer to the following link.
http://javapapers.com/android/difference-between-dp-dip-sp-px-in-mm-pt-in-android/
Here's the formula used by Android:
px = dp * (dpi / 160)
Where dpi is one of the following screen densities. For a list of all possible densities go here
It defines the "DENSITY_*" constants.
ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
Taken from here.
This will sort out a lot of the confusion when translating between px and dp, if you know your screen dpi.
So, let's say you want an image of 60 dp for an hdpi screen then the physical pixel size of 60 dp is:
px = 60 * (240 / 160)
px - one pixel, same as to what is used in CSS, JavaScript, etc.
sp - scale-independent pixels
dip - density-independent pixels
Normally sp is used for font sizes, while dip is used (also called dp) for others.
I've come across a good article about designing Android apps UI for different screen resolutions, and I'd like to leave it here just for somebody searching in this area. Yes, I know that it's somehow described in Google docs (and mentioned in the posts above), I read that but it was not good for me (yeah, I may be too stupid)). It remained unclear to me how to design layouts capable to handle different screen sizes. I hate the DP concept and so on when I need to implement a "flexible" UI layout for different screens. (Hey iOS developers - yes, you're right it's a Storyboard concept).
Android has not bad UI concept, but lacks iOS Storyboard features, unfortunately. Designing flexible UI in Android is not an easy thing (at the best).
Here goes the article that helped me to understand what to do in Android to make layouts for different screen sizes:
JMSTUDIO Blog:- Decide Android App Screen Size
How to Design UI for Android Apps for Different Screen Size
To design an app UI for different screen sizes, our initial design has to
meet a minimum required space for each screen size. Android defines a
minimum size (in dp) for each generalized screen type. Here is an
Android screen size guideline.
When we get the screen size in dp, it is not enough for us to design
the Android app UI. For each screen size, we need to prepare graphics
and bitmap images for each density. Here is an Android screen density
guideline.
For easy calculation, we can follow the 3:4:6:8 scaling ratio between
the four generalized densities. If we create a 36×36 pixel picture for
ldpi device, the rest densities pictures size will be 48×48 for mdpi,
72×72 for hdpi, and 96×96 for xhdpi.
How to Design Android Apps UI in Photoshop
Many designers have problems designing Android app UI in photoshop or another pixel
based graphic design tools because of the density-independent unit, dp.
Designers don’t know how to map dp to pixel. Google also doesn’t give
a clear Android UI design guide for them, though they give a basic
formula for dp and pixel translation.
As Android’s definition, 1pd equal to 1px under 160 dpi device (mdpi).
So we want to design an Android app for xlarge Android devices with
mdpi density, we can define our UI size in pixel as 960 pixels in width
and 720px in height; Follow the same mapping rule, we can get
following Android App screen size UI design guideline:
ADDED: If you are interested in "flexible" UI too, have a look at this library: An Android SDK that provides a new size unit - sdp (scalable dp). This size unit scales with the screen size (this also mentioned in an answer here, about SDP library)
ADDED2 Google has finally understood the usefulness of the iOS Storeboard UI concept, and here goes ConstraintLayout for Android world: Build a Responsive UI with ConstraintLayout
1) dp: (density independent pixels)
The number of pixels represented in one unit of dp will increase as the screen resolution increases (when you have more dots/pixels per inch). Conversely on devices with lower resolution, the number of pixels represented in on unit of dp will decrease. Since this is a relative unit, it needs to have a baseline to be compared with. This baseline is a 160 dpi screen. This is the equation: px = dp * (dpi / 160).
2) sp: (scale independent pixels)
This unit scales according to the screen dpi (similar to dp) as well as the user’s font size preference.
3) px: (pixels)
Actual pixels or dots on the screen.
For more details you can visit
Android Developer Guide > Dimension
Android Developer Guide > Screens
Screen size in Android is grouped into categories ldpi, mdpi, hdpi, xhdpi, xxhdpi and xxxhdpi. Screen density is the amount of pixels within an area (like inch) of the screen. Generally it is measured in dots-per-inch (dpi).
PX(Pixels):
our usual standard pixel which maps to the screen pixel. px is meant for absolute pixels. This is used if you want to give in terms of absolute pixels for width or height. Not recommended.
DP/DIP(Density pixels / Density independent pixels):
dip == dp. In earlier Android versions dip was used and later changed to dp. This is alternative of px.
Generally we never use px because it is absolute value. If you use px to set width or height, and if that application is being downloaded into different screen sized devices, then that view will not stretch as per the screen original size.
dp is highly recommended to use in place of px. Use dp if you want to mention width and height to grow & shrink dynamically based on screen sizes.
if we give dp/dip, android will automatically calculate the pixel size on the basis of 160 pixel sized screen.
SP(Scale independent pixels):
scaled based on user’s font size preference. Fonts should use sp.
when mentioning the font sizes to fit for various screen sizes, use sp. This is similar to dp.Use sp especially for font sizes to grow & shrink dynamically based on screen sizes
Android Documentation says:
when specifying dimensions, always use either dp or sp units. A dp is
a density-independent pixel that corresponds to the physical size of a
pixel at 160 dpi. An sp is the same base unit, but is scaled by the
user's preferred text size (it’s a scale-independent pixel), so you
should use this measurement unit when defining text size
Pixel density
Screen pixel density and resolution vary depending on the platform. Device-independent pixels and scalable pixels are units that provide a flexible way to accommodate a design across platforms.
Calculating pixel density
The number of pixels that fit into an inch is referred to as pixel density. High-density screens have more pixels per inch than low-density ones...
The number of pixels that fit into an inch is referred to as pixel density. High-density screens have more pixels per inch than low-density ones. As a result, UI elements of the same pixel dimensions appear larger on low-density screens, and smaller on high-density screens.
To calculate screen density, you can use this equation:
Screen density = Screen width (or height) in pixels / Screen width (or height) in inches
Density independence
Screen pixel density and resolution vary depending on the platform. Device-independent pixels and scalable pixels are units that provide a flexible way to accommodate a design across platforms.
Calculating pixel density
The number of pixels that fit into an inch is referred to as pixel density. High-density screens have more pixels per inch than low-density ones...
Density independence refers to the uniform display of UI elements on screens with different densities.
Density-independent pixels, written as dp (pronounced “dips”), are flexible units that scale to have uniform dimensions on any screen. Material UIs use density-independent pixels to display elements consistently on screens with different densities.
Low-density screen displayed with density independence
High-density screen displayed with density independence
Read full text
https://material.io/design/layout/pixel-density.html
The screen of a mobile phone is made up of thousands of tiny dots known as pixels (px). A pixel is the smallest element which goes to make the picture. The more the number of pixels to make a picture or wording, the sharper it becomes and makes the smartphone screen more easily readable.
Screen resolution is measured in terms of number of pixels on the screen. Screen resolution is a commonly-used specification when buying a device, but it's actually not that useful when designing for Android because thinking of screens in terms of pixels ignores the notion of physical size, which for a touch device is really really important.
Density independent pixel (dp or dip) allow the designer to create assets that appear in a expected way, no matter the resolution or density of target device.
A density independent pixel (dp or dip) is equal to one pixel at the baseline density or 160 dpi (dots per inch).
1 px/1dp = 160 dpi/160 dpi
2 px/1dp = 320 dpi(2x)/160 dpi
where,
dpi is dots per inch
So, at 320 dpi, 1 dp is equal to 2 px.
Formula
px/dp = dpi/160dpi
Dots per inch (dpi) is a measure of the sharpness (that is, the density of illuminated points) on a display screen. The dots per inch for a given picture resolution will differ based on the overall screen size since the same number of pixels are being spread out over a different space.
Working with density independent pixels help us to deal with a situation like where you have two devices with same pixel resolution, but differing amount of space. Suppose in a case, a tablet and phone has the same pixel resolution 1280 by 800 pixels (160 dpi) and 800 by 1280 pixels (320 dpi) respectively.
Now because a tablet is at baseline density (160 dpi) its physical and density independent pixels sizes are the same, 1280 by 800. The phone on the other hand has a higher pixel density, so it has half as many density independent pixels as physical pixels. So a phone has 400 by 640 density independent pixels. So using a density-independent pixel makes it easier to mentally picture that tablet has much more space than the phone.
Similarly, if you have two devices with similar screen size, but different pixel density, say one is 800 by 1280 pixels (320 dpi), and the other is 400 by 640 pixels (160 dpi), we don't need to define totally different layouts for these two devices as we can measure assets in terms of density independent pixel which is same for both devices.
800 by 1280 pixels (320dpi)=400 by 640 density independent pixel (dp)
400 by 640 pixels (160 dpi)=400 by 640 density independent pixel (dp)
Scale independent pixels(sp) is the preferred unit for font size.
For accessibility purposes, Android allows users to customize their device's font size. Users that have trouble reading text can increase their device's font size. You can normally find this option in the display setting on your phone or tablet under font size. It's often also available through the accessibility settings.
With scale independent pixels, 16 sp is exactly the same as 16 dp when the device's font size is normal or 100%. But when device's font size is large, for example 125%, 16 sp will translate to 20 dp or 1.25 times 16.
If you use dp as the unit for font size, then that piece of text has a specific physical size no matter if the user has customize device's font size. Using sp units will make a better experience for people with impaired eyesight.
Reference: Udacity, Google
sp: scale independent pixel
You should use it with texts because it is automatically scaled according to the font size that is being used by the user in his device.
px: pixel or picture element is the single point on the screen
Pixels(px) – corresponds to actual pixels on the screen. This is used if you want to give in terms of absolute pixels for width or height.
Density-independent Pixels (dp or dip) – 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”.
Scale-independent Pixels(sp) – this is like the dp unit, but it is also scaled by the user’s font size preference. It is recommended you use this unit when specifying font sizes, so they will be adjusted for both the screen density and user’s preference.
Always use dp and sp only. sp for font sizes and dp for everything else. It will make UI compatible for Android devices with different densities.
You can learn more about pixel and dp from
https://www.google.com/design/spec/layout/units-measurements.html#units-measurements-density-independent-pixels-dp-
Source URL:- http://www.androidtutorialshub.com/what-is-the-difference-between-px-dp-dip-sp-on-android/
I want to provide an easy way to understand dp. In fact, I think dp is the easiest one to understand. dp is just a physical length unit. It's of the same dimension as mm or inch. It's just convenient for us to write 50dp, 60dp rather than 50/160 inch or 60/160 inch, because one dp is just 1/160 inch whatever the screen size or resolution is.
The only problem is that, the android dpi of some screens are not accurate. For example, a screen classified to 160dpi may have 170dpi indeed. So the computation result of dp is fuzzy. It should be approximately the same as 1/160 inch.
SDP - a scalable size unit - basically it is not a unit, but dimension resources for different screen size.
Try the sdp library from Intuit. It's very handy to solve unit problems, and you can quickly support multiple screens.
Usage
android:paddingBottom="#dimen/_15sdp" for positive and android:layout_marginTop="#dimen/_minus10sdp" for negative sdp sdp
It has equivalent value in dp for each size in values-sw<N>dp folders (sw = smallestWidth).
Attention
Use it carefully! In most cases you still need to design a different layout for tablets.
Example
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_minus10sdp"
android:paddingBottom="#dimen/_15sdp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="♡"
android:textColor="#ED6C27"
android:textSize="#dimen/_70sdp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="U"
android:textColor="#android:color/black"
android:textSize="#dimen/_70sdp" />
</LinearLayout>
You can use db for text size, but I prefer ssp for text size.
For more details, check the library GitHub page.
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".
Scale-independent Pixels - this is like the dp unit, but it is also scaled by the user's font size preference.

Categories

Resources