Android Screen sizes - android

I need to know the screen sizes of android devices to support multiple screen sizes application.

Look at this table: http://developer.android.com/guide/practices/screens_support.html#testing
You can use the pie chart here to have an idea of relative screen size usage: http://developer.android.com/resources/dashboard/screens.html
For a list of screen sizes, resolutions and dpi values, take a look at: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
To calculate the real dpi value, check here: http://en.wikipedia.org/wiki/Pixel_density#Calculation_of_monitor_PPI

I don't think there's a comprehensive list of all existing screen sizes, since new devices are coming out all the time. Have you seen the page on Screen Sizes and Densities and the documentation on Supporting Multiple Screens?

Different screen sizes are as follows.
xlarge screens are at least 720dp 960dp
large screens are at least 480dp x 640dp
normal screens are at least 320dp x 470dp
small screens are at least 320dp x 426dp
If you are plan to make an application which support for multiple devices, also you have to crate different layout directories for put different layouts.
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
If you are plan to add different sizes of images, put them in following folders accordingly. Android OS will automatically take the most suitable image out of them.
res/drawable-ldpi/my_icon.png // bitmap for low density
res/drawable-mdpi/my_icon.png // bitmap for medium density
res/drawable-hdpi/my_icon.png // bitmap for high density
res/drawable-xhdpi/my_icon.png // bitmap for extra high density

Android supports multitude of screen sizes. There is no list of specific screen sizes. Only approximate ranges. Read more at "Supporting Multiple Screens".

LDPI MDPI HDPI
Please see this: http://developer.android.com/guide/practices/screens_support.html
then this: http://developer.android.com/resources/dashboard/screens.html
then this: http://developer.android.com/guide/topics/resources/providing-resources.html

In terms of supporting different screen sizes I would start by taking a look at the Screen Support Reference, might be able to solve your problem better. To see a list of specific sizes take a look at Table 2

Here it comes!
(240, 320)
(240, 400)
(320, 480)
(360, 640)
(480, 640)
(480, 800)
(480, 854)
(540, 960)
(600, 800)
(600, 1024)
(640, 960)
(720, 1280)
(768, 1280)
(768, 1024)
(800, 1280)
(1080, 1920)
(1200, 1920)
(1600, 2560)
fresh from http://en.wikipedia.org/wiki/Comparison_of_Android_devices 's html sources parsed with:
import re
s = ""
with open("sizes.html", "r") as src:
s = src.read()
res = re.findall('([0-9]+)\s*[×xX]\s*([0-9]+)', s)
sizes = set()
for match in res:
size_int = [int(match[0]), int(match[1])]
size = (min(size_int), max(size_int))
if size not in sizes:
sizes.add(size)
sorted_sizes = list(sizes)
sorted_sizes.sort(key=lambda sz: sz[0])
for sz in sorted_sizes:
print(sz)
(forgive my python)

Here's a little function to know the inch size of your device in case you need it to support multisize screen :
public double getInchSize()
{
DisplayMetrics metrics = getResources().getDisplayMetrics();
return Math.hypot(metrics.widthPixels/metrics.xdpi, metrics.heightPixels/metrics.ydpi)
}
Hope it can help

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)

how to know which phone support which layout(hdpi , mdpi and xhpi)?

I'm a little confused about how to determine which phones support what layout types. I've done some research but haven't found a satisfying answer.
For example, I've found the below guide:
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
However, I still have some concerns:
Samsung grand (480*800) and HTC wild fire S (320*480) both support MDPI. These screens have very different resolutions, yet have the same layout type?
Galaxy note 2 (1280*720) support HDPI. If HD (720p) is only HDPI, when what device/resolution supports XHDPI?
I've already asked a related question here: How to set layout on 7" two different tablet?.
My most important question, however, is this: How do I know which devices or screen resolutions support each layout type?
Android treats mdpi (160 pixels/inch) as the base density. So for mdpi devices, 1 dp = 1 pixel. At higher densities, there are more pixels per inch (240 for hdpi, 320 for xhdpi).
AutoMatic Scaling by Android itself:
Android attempts to make graphic images occupy the same physical dimensions on the screen regardless of the device pixel density. So if all it finds is an mdpi resource, and the device is hdpi, it will scale the graphic by 240/160 = 150%, and it will double the size of the graphic for xhdpi.
Using different versions of graphics :
If you don't want this automatic scaling (which can make graphics look poor), you can simply supply your own version of graphic resources for use at higher densities. These graphics should be of the same size that Android would scale an mdpi resource.
Note : the pixels/inch that was stored in the image file has nothing to do with this. It's all based on where you put the graphics files in the resources directory for your project. Any graphics placed in res/drawable are assumed to be properly sized for mdpi displays, as are graphics placed in res/drawable-mdpi. Image files that it finds in res/drawable-hdpi are assumed to be properly sized for hdpi displays, etc. When your program runs on a particular device, Android will first look for a graphic that matches the display density of that device. If it does not find one but instead finds one for a different density, it will use that and automatically scale the image based on the above rules.
As 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
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
this way, for screens with the same size but different DPI, all the images seem the same size on screen.
look into these details: android manages all this by itself, you just have to provide layouts and images in relative folders
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
res/drawable-mdpi/my_icon.png // bitmap for medium density
res/drawable-hdpi/my_icon.png // bitmap for high density
res/drawable-xhdpi/my_icon.png // bitmap for extra high density

android how to support multiple screen

Thais is what I have done. I try to support this screen sizes:
xlarge screens 640dp x 960dp
large screens 480dp x 800dp
normal screens 320dp x 400dp
small screens 240dp x 400dp
So I create etc. background images with that sizes (640dp x 960dp, 480dp x 800dp, 320dp x 400dp and 240 x 400). I put images in folders drawabale-xhdpi, drawabale-hdpi, drawabale-mdpi and drawabale-ldpi.
When I have xlarge screen with hdpi density (it use images from hdpi folder), graphic is bad (images are not large enough). So how to use that xlarge image when I have hdpi density. Do I have to create more images and put them in some places? This is a game, I draw all in canvas, don't use layouts for drawing images.
Thanks.
You can add new drawables in a drawable-xlarge-hdpi folder
use this path to save your image
res/drawable-xhdpi/my_icon.png // bitmap for extra high density
Check this Supporting Multiple Screens for more clarifications of multiple screen support.
Take a look at this link - Providing Resources
You can have an image in drawable-xlarge-hdpi folder
always use relative layouts to support multiple screens. see here Android layouts for same density different diagonal length

Android screen resolutions

I am following this tutorial link
There three types of screens
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
But there are three folders
drawabale-hdpi
drawabale-mdpi
drawabale-ldpi
I placed images of xlarge in hdpi
that of large in mdpi
and that of normal in ldpi
but where to place the images of small screens?
Sorry for bad english
For example, The following is a list of resource directories in an application that provides different layout designs for different screen sizes and different bitmap drawables for small, medium, high, and extra high density screens.
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
res/drawable-mdpi/my_icon.png // bitmap for medium density
res/drawable-hdpi/my_icon.png // bitmap for high density
res/drawable-xhdpi/my_icon.png // bitmap for extra high density
and Screen Sizes.
I hope this help.
hdpi, mdpi and ldpi refer to the screen density in dots-per-inch. This is completely separate from the screen size (small, large, etc).
You can have large screen with low density, or a small screen with high density, etc.
You can cater for different screen sizes by putting different layout resources in res/layout-small, res/layout-large, etc.
These are two different things - hdpi/mdpi/ldpi are screen densities (i.e., how many pixels per square centimeter) while xlarge/large/normal/small are screen sizes (the physical dimensions of the screen). So the small screen images would go in drawable-small, normal in drawable-normal, etc.
There's a lot more info about this stuff on the Android developer website.
Screen size has no relation with density. xlarge screen does not mean it has hdpi density. For example tab like galaxy 10.1 pr motorola xoom has xlarge screen but mdpi density so for them you make a separate folder drawable-xlarge. and for this you have to add android:xlargeScreens="true" in manifest.
And devices like galaxy s2 or htc desire has hdpi density. Devices with small screens like galaxy pop are mostly have ldpi density, normal screens like galaxy ace are mostly mdpi devices and devices with large screens like galaxy s2 are mostly hdpi devices, and some devices like tab P1000 have large screens but mdpi density and for them you have to make folder drawable-large-mdpi.

Android multiple screen sizes with same density

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);

Categories

Resources