I'm trying to create main activity in my application using GridView. I need to have a grid 3x3. Every cell contains ImageView (icons for different actions). All images must have the same size. And my question is: what sizes of image I must use? I watched tutorial and found a table with sizes for different resolutions and density. But I didn't understand. For instance, I have mdpi density and screen size 480*800. Does it mean that I should use icons 160*266 for this screen? And what sizes should be for other densities and screen sizes? How can I calculate them?
This is one of the most asked question, you can search for more details, but let me give you briefly how it works.
MDPI is considered as the base line and following are the scales
MDPI - X1
HDPI - X1.5
XHDPI - X2
XXHDPI - X3
XXXHDPI - X4
Now you must be thinking what is this.
Since you want to have 3X3 grid with cell of equal size, you can consider the following.
In general mdpi screen size is 360 X 640, so each image size will be 120dp X 212dp Approx.
For mdpi screen, your Image size should be 120px X 212px
For hdpi screen, your Image size should be 180px X 318px
For xhdpi screen, your Image size should be 240px X 424px
For xxdpi screen, your Image size should be 360px X 636px
For xxxdpi screen, your Image size should be 480px X 848px
Now where you should place these images?
Project -> app -> src -> main -> res
Here, create folders with name drawable-mdpi, drawable-hdpi, etc, and place respective images in these folders.
Thats it for supporting multiple screen densities.
According to docs, MDPI and HDPI screen sizes are given considering
their aspect ratio to 3:4, but since most of the users have HD
devices with aspect ratio of 9:16, you can consider the most standard
screen size in Market i.e. 1080 X 1920 which corresponds to XXHDPI and
acts as baseline to make the assumption of considering MDPI to be 360
X 640. For high quality apps, trade off has to be made for lower
devices since most of the existing users have XXHDPI or higher
devices.
Related
I have 4 sets of images
Resolutions DPI Directory
240 x 320 120dpi - drawable-ldpi
320 x 480 160dpi - drawable-mdpi
480 x 800 240dpi - drawable-hdpi
1280x 800 320dpi - drawable-xhdpi
But when I tested it at ASUS transformer with resolution 1280x800 and DPI 224.
It loaded graphics from drawable-hdpi.
If I will add another folder with name drawable-xlarge, It will load desired images but it will increase the size of application as well.
My questions are as follows
1 - What is the best practice to support all screen sizes and DPI?
2 - Is there any way to force load drawable of particular DPI w.r.t screen size?
3 - What is the solution recommended for my problem without replicating the graphics?
But when I tested it at ASUS transformer with resolution 1280x800 and dpi 224. It loaded graphics from drawable-hdpi.
That is because the ASUS Transformer is an -hdpi device. Hence, it is working properly.
What is the best practice to support all screen sizes and dpi?
Usually, images only vary based on density, and so your current structure is fine.
If you elect to have images that vary both on screen size and density, you will need to make more directories (e.g., res/drawable-xlarge-hdpi/) and images for the
Is there any way to force load drawable of perticular dpi w.r.t screen size?
Density and screen size have nothing to do with one another.
What is the solution recommended for my problem without replicating the graphics?
According to your "question", you do not have a problem. Hence, there is no recommendation for your non-problem.
I have looked at the pages here on stackoverflow regarding this issue and followed up by looking at the links provided as some of the answers provided but I am still very confused. I use Photoshop to develop my screen shots in my android apps. It breaks down to this, there are four folders in the res folder for the different phone types Small Medium Large X-Large.
If I want to create an image to be used as a background that fills in the background completely and I am creating that image in the default resolution on Photoshop of 72 pixels per inch, what methodology and dimensions should I use for each image?
The specification I use in the manifest file would be set up as fill parent for both width and height.
I do understand there are many types of phones with different screen sizes but I need the most generic
As I understand it the images will be resized to fit screens but I that in itself leads to the creation of strange images if the original is not originally setup to be somewhat close.
So I need the somewhat close dimensions of a typical background image for each folder.
Small -> X_Dim x Y_Dim
Medium -> X_Dim x Y_Dim
Large -> X_Dim x Y_Dim
X-Large -> X_Dim x Y_Dim
Four folders four sets of dimensions
Again I am using Photoshop and 72 pixel/inch
The screen sizes are different concept with screen dpis
So, based on your question the most generic screen resolution for each dpi are:
ldpi 240 x 320px
mdpi 320 x 480px
hdpi 480 x 800px
xhdpi 720 x 1280px
I am talking about the generic screen resolution that each ldpi/mdpi/hdpi/xhdpi commonly has, so if you could create assets with these four sizes, it will fit most devices.
I Have a few general questions about Android screen / DPI / resolution indepence.
Basically, I am taking specifically about sprite-based apps, like ones based on Surfaceview for example.
Every guide I've read (including the official one) says that you should only work with the DPI and not the resolution.
However, what happens when two devices have different DPI's/screen size but the same resolution? Take the Galaxy tab 10.1 (1280 x 800 - DPI aprox 150) and the Galaxy Note (1280 x 800 aprox 285 DPI I think??)
When displaying a sprite of say 50 x 50 on each of these, it will appear to be the same size relative to the screen size. However, if Android grabs a difference size sprite because it detects a different DPI (ie, from LDPI, HDPI etc), then the sprite will appear to be bigger on the Note relative to the screen size than it would on the Tab.
Can anyone please set me straight on this as I just cannot work it out!! Thanks all.
A 50 x 50 sprite on a 150dpi screen will appear much larger than a 50 x 50 sprite on a 285dpi screen. Android's resource resolution algorithm is intended to allow you to define a larger (in pixels) image for use on higher density screens.
If you want the sprite to be the same size relative to the screen regardless of the pixel density, then you can put the images in the drawable-nodpi folder and they won't be scaled by the system. You can even decide which size image to use in code after querying the screen size. (As of 3.2, you can have resource folders that depend on screen pixel size, but I think they will still scale with dpi.)
Screen resolution refers to the screen dimension in pixels. Pixel density refers to how many pixels it takes to fill an inch of screen.
I've read 10 articles yet still cant find any relation between ldpi, mdpi, hdpi and the actual dimensions in pixels!? Can anybody give a straightforward answer please(if there is one!)
I'm basically trying to put together a splash screen that needs to work on multiple devices without stretching - but i'm struggling as everything I try is either squashed or stretched!?
Cheers
Paul
The ldpi, mdpi and hdpi refer to screen density, which means how much pixels can fit into a single inch.
the ratio in pixels between them is:
ldpi = 1:0.75
mdpi = 1:1
hdpi = 1:1.5
xhdpi = 1:2
xxhdpi = 1:3
xxxhdpi = 1:4
so lets take an image with about the size of 100X100:
for mdpi it should be 100X100
for ldpi it should be 75X75
for hdpi it should be 150X150
for xhdpi it should be 200X200
for xxhdpi it should be 300X300
for xxxhdpi it should be 400X400
this way, for screens with the same size but different DPI, all the images seem the same size on screen.
Also you have multiple screen size types small, normal, large, xlarge and each one of them can be ldpi, mdpi, hdpi, xhdpi, xxhdpi (Nexus 10) or xxxhdpi.
You can try to create a splash screen image that fit to each and every screen type
which gives you 4*5 = 20 different images (it seems to much for me).
For now only the Nexus 10 is at the xxhdpi category.
Install ImageMagick and use this shell script to generate your splash and icon files for multiple devices - iOS, Android, Bada and Windows Phone. You can use cygwin/gitbash if you are on Windows
I just did and I'm pretty happy with it :-)
The screen sizes are inside the script and are -
480x800 - screen-hdpi-portrait.png
320x200 - screen-ldpi-landscape.png
720x1280 - screen-xhdpi-portrait.png
320x480 - screen-mdpi-portrait.png
480x320 - screen-mdpi-landscape.png
200x320 - screen-ldpi-portrait.png
800x480 - screen-hdpi-landscape.png
The definitions are:
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. (Android does not currently
support screens smaller than this.)
Also, check out this blogpost from Dianne Hackborne:
http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html
Probably the easiest thing is to use an image view and set the scaletype to CENTER_CROP.
(Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view).
Make sure that you use the src tag rather than setting the background.
<ImageView
android:id="#+id/home_video_layout"
android:src="#drawable/splash_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
/>
Updated:
Understanding Screen Densities and the “dp”
Resolution is the actual number of pixels available in the display, density is how many pixels appear within a constant area of the display, and size is the amount of physical space available for displaying your interface. These are interrelated: increase the resolution and density together, and size stays about the same. This is why the 320x480 screen on a G1 and 480x800 screen on a Droid are both the same screen size: the 480x800 screen has more pixels, but it is also higher density.
To remove the size/density calculations from the picture, the Android framework works wherever possible in terms of "dp" units, which are corrected for density. In medium-density ("mdpi") screens, which correspond to the original Android phones, physical pixels are identical to dp's; the devices’ dimensions are 320x480 in either scale. A more recent phone might have physical-pixel dimensions of 480x800 but be a high-density device. The conversion factor from hdpi to mdpi in this case is 1.5, so for a developer's purposes, the device is 320x533 in dp's.
I have found this online dip <--> pixels calculator very useful.
https://pixplicity.com/dp-px-converter/
I support previous answers but don't forget the power of Draw9Patch or using NinePatchDrawables
These refer to screen pixel density, not screen dimension. You need to look into screen size specifiers like small, medium, large, and xlarge instead if you really need to change behavior based on screen size in pixels.
The Android docs explain what densities and sizes match these identifiers.
Android devices can have different width-to-height ratios, while your image has a fixed one. If you do not want your image stretched, you will have to fill the blank spaces above and below or left and right.
I'm confused regarding the densities. I see that with medium density, the screen resolution could be either 320x480, 480x800, or 480x854. So if I have an image thats 300px wide in the mdpi folder, how is it going to look the same size on all 3 different screen sizes (mainly 320x480 vs the other 2)?
And by look the same size, I mean scale to be bigger or smaller depending upon the screen size. Thanks.
There are three distinct but linked concepts to understand here: screen density (pixels per inch/centimeter, or commonly known as DPI from dots per inch in printers), physical screen size (in inches or centimeters) and number of pixels (also known as resolution, in pixels).
These terms are not interchangeable, and you need to understand how they interlink to not be confused with the issue. Generally, you can ignore physical screen size since that's already accounted for in the density. For example a screen 3 inches wide and 300 pixels across will have a DPI of 100. Furthermore phones screens tend to have about the same physical size, even if the number of pixels is very different.
So, let's consider the screen of a G1 or Hero which has a resolution 480x320 and a density of approx 160dpi. An image 300 pixels wide will be 1.875 inches across. This is calculated by pixel size (300) / density (160). Now if you compare this to the screen of the Nexus One, Droid or similar, these models have a higher resolution screen of approx 800x480 with a high density of approx 240dpi. If you display the same 300px wide image, it will now only physically be displayed at about one and a quarter inches across. In other words, it will be much smaller. This can be a problem because if the image contains text, then the text might not be readable anymore.
Android can be told to automatically scale images to fit these different screens so that it still looks to be the same size. This is done by setting sizes in Density Independent pixels. If something is 100dp wide, it will be 100px wide on a medium density screen. On a high density screen, it will be 150px wide, but they will both look about the same size on the actual screen. However, if you do this, your image can go a bit blurry. It's the same as when you zoom into a photo too closely in a picture viewing program; the edges go blurry since it 'stretches' them while you zoom.
The way to solve this is to use the mdpi, hdpi and so forth folders. You're giving Android an image that has already been scaled, so that it doesn't have to do it itself. Obviously if you just stretch the image yourself in Photoshop, then it won't look any better. But normally one is resizing very large images down to make them fit the mobile screen. In that case, you just resize them three different times, each into a different resolution.
So to finally answer your specific question: if you have an image placed in your mdpi folder, it will be exactly the same size regardless of the screen resolution, as long as they are all the same density. What will change is how much space around them, e.g. a 320x320px wide image would fill most of a 320x480 screen, but only about a third of a 480x800 screen. However, as noted above, generally the higher resolution phones also have a more dense screen. In that case, Android won't look in your mdpi folder for the image - it will go to the hdpi folder, and if it can't find it there, it will take the default "drawable" folder. Then if you've used DP it will automatically scale it, or if you've used PX, it will leave it as is, and it will just look smaller.
There! A very long answer for you. I hope it makes sense.
For completeness, also check these option for controlling layout:
Directory qualifiers:
Size: small, normal, large
Density: ldpi, mdpi, hdpi, nodpi(no auto-scale)
Aspect ratio: long, notlong
Orientation: land
Usage:
res/layout/my_layout.xml
res/layout-small/my_layout.xml
res/layout-large/my_layout.xml
res/layout-large-long/my_layout.xml
res/layout-large-land/my_layout.xml
res/drawable-ldpi/my_icon.png
res/drawable-mdpi/dpi/my_icon.png
res/drawable-hdpi/my_icon.png
res/drawable-nodpi/composite.xml
Restricting your app to specific screen sizes(via the AndroidManifest):
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true" />
...
</manifest>
And for code level tweeking:
float scale = getContext().getResources().getDisplayMetrics().density;
And don't forget:
dpi = 160; //At 160dpi
pixels = dips * (density / dpi)
It's all in this doc:
developer.android.com:Supporting Multiple Screens
So if I have an image thats 300px wide
in the mdpi folder, how is it going to
look the same size on all 3 different
screen sizes (mainly 320x480 vs the
other 2)?
How the image looks, physically, is driven by screen density, not screen size. Your -mdpi folder is not tied to screen size -- it is tied to screen density.
This is what Device Independent Pixels (DIPs) are for. Instead of 320px write 320dip.
http://developer.android.com/guide/practices/screens_support.html
Could you please confirm the formula for calculating the screen density?
As I have read, the following is the formula:
Density = SQRT (wp^2 + hp^2)/screen size
wp -> width of the screen (in px)
hp -> height of the screen (in px)
screen size -> Physical screen size (diagonal inches)
screen size (320x480) = SQRT(102400 + 230400) /160 = 3.6 inches
screen size (480x800) = SQRT(640000 + 230400) /160 = 5.8 inches
screen size (480x854) = SQRT(729316 + 230400) /160 = 6.12 inches
So, the layouts (UI screens) are driven by screen sizes (small: <3", normal <4",
large >5") and drawable resources (images) are driven by screen densities.
And, the size of the image (in pixels) does not change if the density of the screens
(320x480, 480x800, or 480x854) are the same.
Could you please confirm?
Thanks,
Ram
Actually the code to calculate physical screen size for devices is the following one:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels/dm.xdpi,2);
double y = Math.pow(dm.heightPixels/dm.ydpi,2);
double screenInches = Math.sqrt(x+y);