I have created an android application that is working fine in the mobile handsets. Now I want it to be compatible for 7" and 10" tablets as well. For this I have created drawable folders as well as layout folders (sw600dp for 7 and sw720dp for 10).
There are many 7 inches tablets in the market. With different pixel as well as screen density.
For instance - 7 inch tablets range from Width x Height (600 X 1024) to (1200 x 1920) with PPI ranging from 170 to 323.
Similarty 10 inch tablets range from Width x Height (768 X 1280) to (1600 x 2560) with PPI ranging from 132 to 300.
I have created my image resources in the sw600dp and sw720dp considering the base size of the 7 and 10 inch tablets which is 600 x 1024 and 768 x 1280. I have designed my layouts in a way that my application looks fine in both these pixel and PPI densities.
BUT WHAT ABOUT THE REST OF THE DEVICES?
I need a way to make sure that my application looks great on all the 7 and 10 inches tablets available in the market. How do I achieve this?
Google has recommended that developer should focus on the density of the device rather its size but here problem is that If I try the DisplayMetrics to find the density of the current device and show my drawable and layouts accordingly - possibility is that I might display wrong drawable in wrong layouts since the PPI range of 7 inch (170 - 323) and 10 inch (132 - 300) overlap with each other.
How do I make sure to display right drawable and layouts for the current device? Do I need to create multiple drawable and layouts folders for the 7 inch and 10 inch tablets or will 2 drawable and 2 layouts (sw600dp and sw720dp) will suffice for this?
Kindly suggest as I am facing this problem for many days now. TIA.
First of all, you don't need to check DisplayMetrics for all the devices. You need not worry about the "actual screen density"; instead look for the "generalized density".
From the docs,
A set of six generalized densities:
ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
You need to specify your layouts and drawables in their appropriate density specific folder to get them right on the different devices.
For example, you have some image to show, then create copies of that image with different dimensions (small size image for small display, large size image for large display). Once you get these images ready then put them into the density folders (for drawables it will be drawable-hdpi/, drawable-mdpi/ etc). Thats it. Now when your app runs, system will detect the screen density and will take the image from appropriate folder.
For details on this, read Supporting Multiple Screens.
Related
I have an app in the play store which runs on all mobiles and now I want to release it on tablets as well.
1) The images have been designed for xhdpi screens. So I think that will be sufficient to support tablets as well or should I redesign the images seperately for tablets?
2) I want to split dimens.xml into 3 categories -
dimens.xml for all mobile phones
dimens.xml for all 7 inch tablets
dimens.xml for all 10 inch tablets
The solution I came up with is divide the values folder like below -
values/dimens.xml
values-sw620dp/dimens.xml
values-sw720dp/dimens.xml
but since few mobile phones might fall into values-sw620dp/dimens.xml or values-sw720dp/dimens.xml, What is the appropriate way to divide dimens.xml into 3 categories??
Please do not post the below picture as I want to divide into 3 categories
Following is Struture Answered by Many
1) There is no tablet device in the market with higher density than xhdpi. Therefore, xhdpi images are sufficient to support tablets
2) Dividing the values folder as below will be helpful
- values\dimens.xml
- values-land\dimens.xml
- values-sw600dp\dimens.xml
- values-sw600dp-land\dimens.xml
- values-sw720dp\dimens.xml
- values-sw720dp-land\dimens.xml
The suffix -land is used for lanscape orientation.
Mobile phones do not fall into the sw600dp or sw720dp category. I think you are confused between dp and px.
Example:
Take Samsung Galaxy S7 Edge.
Resolution : 1440 x 2560px
Density : xxxhdpi
Converting 1440px to dp at xxxhdpi density, you get 320dp (Convert px to dp)
Therfore the width of Samsung Galaxy S7 edge in dp is 320dp and will fall in values\dimens.xml file
If you take a Tab and find dp similarly, you will notice that the dp will be greater than or equal to 600dp.
I am having two android devices which are having the same resolution and PPI. But when i run my application for one device that is Samsung Tab 4, the resources are called from normal layout folder. But for another device that is Samsung J Max, it is from layout-600 folder. Why this is behaving differently for these devices? Any suggestions would be greatly appreciated.
You should check This Google Article. It pointed out that:
In this context, the Samsung has another little surprise: If you do the arithmetic, its screen has 170 DPI, which is far from the densest among Android devices. Still, it declares itself as “hdpi” (and as having a “large” screen size). The reason is simple: It looks better that way.
That means your Tab ppi is 170 (not 220ppi). As a result: 800 width, 170 ppi --> 800/(170/160) > 600. That's why your Samsung Tab 4 resource is from folder "layout-sw600dp"
The 600 qualifier in layout-600 has to do with the screen dimensions in dp and not necessarily with the DPI or the screen resolution in pixels. Other factors like the aspect ratio and the diagonal size of the screen are also taken into consideration.
You can determine the dimensions of your screen in dp programmatically using the instructions in this post:
Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
I bet that the value of screenWidthDp is different between those devices.
This depends on Density Pixels(dp) of Android Devices which very from device to device and according to that Android device detect automatically from which layout folder it will show the UI, here is the little information how it works :
As you design your UI for different screen sizes, you'll discover that
each design requires a minimum amount of space. So, each generalized
screen size above has an associated minimum resolution that's defined
by the system. These minimum sizes are in "dp" units—the same units
you should use when defining your layouts—which allows the system to
avoid worrying about changes in screen density.
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
A set of six generalized densities:
ldpi (low) ~120dpi
mdpi (medium)
~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi
(extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
For more info please read google doc :https://developer.android.com/guide/practices/screens_support.html
Yesterday I already asked a question about this here. After that I saw this on the official android developer page:
So you can have a 1024x600px screen device with ldpi and a screen with the same resolution with mdpi.
Furthermore you can have a 600x1024px screen device with mdpi and a screen with the same resolution with hdpi.
I have an image, that takes 20 % of the screen's height and width on every device.
I want to make 5 versions of that image (with different resolution) for each drawable folder.
In my past thread I got this answer:
ldpi: 0.75
mdpi: 1.0
hdpi: 1.5
xhdpi: 2.0
xxhdpi: 3.0
xxxhdpi: 4.0
These are the scale factors.
So if my image has a resolution of 50 x 100 px in mdpi it is supposed to have a resolution of 75 x 150 px in hdpi.
I understand that.
The question now is, how am I supposed to know what resolution my image should have in the mdpi folder, if the resolutions for mdpi are totally different (as you can see in the image above -> from 320x480 to 1280x768).
Thanks !
The drawables should be created at a resolution that makes them the right physical size when displayed on the screen. If you have an icon that is supposed to be 1/2 inch by 1/2 inch on an MDPI screen, then the image should be 80px by 80px. This size should be irregardless of the physical dimensions of the screen; the same drawable on a 1280x768 MDPI tablet is supposed to be 1/2 inch by 1/2inch.
If the icon in question should be larger on the tablet for some reason, then you would need to introduce the drawable-swXYZdp-mdpi folder that Der Golem mentioned above. In this folder, you would be able to create a version of the icon that had a larger physical size (say 3/4 inch) that will be loaded on the tablet.
Nexus 7: 7" 1280x800
Galaxy tab 10.1 10" 1280x800
I want my app to run on 7 and 10 inch tablets. As far as I know, I have to include these layout folders in my app:
for 7 inch tablets
layout-sw600dp
layout-sw600dp-port
for 10 inch tablets
layout-sw720dp
layout-sw720dp-port
It runs fine on the nexus 7, but loads the sw600dp layouts on the 10" tablet.
If I include these default folders:
layout
layout-port
10" galaxy tab loads layouts from these.
If I only include the default layout folders and the sw600dp one, it crashes on the nexus7.
How am I supposed to support phones, 7" tablets and 10" tablets, if the 10" galaxy tab won't load the sw720p layouts?
edit:formatting
The problem was, that I had no default layout folder.
I tried getting by, using only the sw600dp and sw720dp folders. I still have no idea why they don't work, but I don't care. I can't use swxxxdp <3.2 anyway, so screw that.
So if you want to write an app, that has to support phones(2.2+), 7inch tablets and 10 inch tablets, use the following oldschool stuff:
layout this is the default, it is needed even if you don't plan to support phones!
layout-large for 7" tablet (works on emulator and nexus7)
layout-xlarge for 10" tablet (works on emulator and galaxytab10.1)
Other people have came to the same conclusion too.
I am also facing such problem in my application. But I found a good solution for this.
I have only one layout for tablet and directory name is layout-sw600dp.
Now, when part came to height and width problems, I have created several different values directory in which i place dimensions and font size and other stubs. So there will be no constant value in layout of tablet screen.
androd:layout_width:"60dp" // i drop this scenario
androd:layout_width:"#dimen/tab_width" // i used this scenario
and your values directory name will be like
values-xlarge
values-large
All the values will be fetched from your values directory. It will not create different layout, but one layout can be used multiple times.
Following are words of Developer.android site.
Configuration examples
To help you target some of your designs for different types of devices, here are some numbers for typical screen widths:
320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
480dp: a tweener tablet like the Streak (480x800 mdpi).
600dp: a 7” tablet (600x1024 mdpi).
720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).
Using the size qualifiers from table 2, your application can switch between your different layout resources for handsets and tablets using any number you want for width and/or height. For example, if 600dp is the smallest available width supported by your tablet layout, you can provide these two sets of layouts:
res/layout/main_activity.xml # For handsets
res/layout-sw600dp/main_activity.xml # For tablets
===
In this, you can see that, layout for 1280*720 is under layout-sw720dp so instead of creating layout-normal-xlarge you should use this thing which lets you to decide differences. Instead of identify differently using layout-large-mdpi and layout-large-ldpi, are't you just identify by its smallest width? Because, android providing drawables directory for different images, only thing is its resolution. And you have above solution.
Edit
Then you must have to develop different layouts. No other option. I found at http://jamil.fluidsoul.net/2011/03/06/creating-android-applications-for-multiple-screen-sizes.
Low density Small screens QVGA 240x320 (120dpi):
layout-small-ldpi (240x320)
layout-small-land-ldpi (320x240)
Low density Normal screens WVGA400 240x400 (x432) (120dpi):
layout-ldpi (240 x 400 )
layout-land-ldpi (400 x 240 )
Medium density Normal screens HVGA 320x480 (160dpi):
layout-mdpi (320 x 480 )
layout-land-mdpi (480 x 320 )
Medium density Large screens HVGA 320x480 (160dpi):
layout-large-mdpi (320 x 480 )
layout-large-land-mdpi (480 x 320)
Galaxy Tab ( 240 dpi ):
layout-large (600 x 1024)
layout-large-land (1024 x 600)
High density Normal screens WVGA800 480x800 (x854) (240 dpi):
layout-hdpi (480 x 800)
layout-land-hdpi (800 x 480)
Xoom (medium density large but 1280x800 res) (160 dpi):
layout-xlarge (800 x 1280)
layout-xlarge-land (1280 x 800)
Yes, you should use layout-dependent folders but also make sure any device independent layouts go in your res/layout folder.
This is mentioned on the Android developer site but to reiterate their point, if you have a layout that is only available in an layout-xlarge folder on an app that supports say large and normal sized devices as well, the app will crash as smaller devices will not be able to find any match for this resource.
Here is a good folder structure, start with:
res/layout
Keep a device-independent layout in there, you can avoid this if you are accounting for every possible qualifier type but this is still the safer option.
If you want to add specific layouts for say 7 and 10 inch tablets, use all of the following:
res/layout-large
res/layout-xlarge
res/layout-sw600dp
res/layout-sw720dp
res/layout-sw800dp
And so on for any specific device screen widths you want to support. It should be noted that sw600 supports the smallest possible width, so avoids the use of the screen width when the device is held landscape. Using the swxxxdp qualifers are preferred but these were added in API 13 so you will still need large, xlarge for older Android OS.
Regarding use of the dpi, be aware that if you ONLY set one density qualifier for a size, so layout-large-mdpi for example, then any devices that match the large qualifier will use layouts from here instead of another folder, this is due to the Best Match criteria, which you can read about here. It will match it as a large device before it will match the density so non-mdpi density screens will still use these layouts.
To counter this, you will have to include folders for whatever other densities you support as well, so layout-large-hdpi following on from the above example, and include in this folder hdpi versions of layouts that you have used in the mdpi folder if you require them to be different.
Avoid duplicating your layouts as well of course, don't copy device-independent layouts into every unused folder if you only need them in res/layout, try and only keep the layouts that need these qualifiers in the folders and organise them properly, making sure your folders are named with the qualifiers in the right order of precedence to prevent using the wrong folder for a density/size combination.
This is very strange, since you are doing the correct thing.
The sw600dp qualifier should be selected by the Nexus 7.
If available, the sw720dp qualifier should be selected by the Galaxy Tab.
Are you sure it crashes when trying to find an appropriate layout? Android may find the correct layout, but something in the layout xml file may be missing and the crash is caused by that.
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.