I have gone through all of the Android docs about handling multiple screen sizes but I still haven't been able to find an answer to this question or how to handle this.
If there are two phones that have the same dpi level (such as both being hdpi) I can provide one resource for them and set the layout parameters as such:
<ImageView
android:id="#+id/icon"
android:layout_width="94dp"
android:layout_height="94dp"
>
The "icon" in this instance is large enough so that it will scale down to fit that layout in all cases. In an ideal world, I would assume that the icon would appear the exact same size on all hdpi devices, however when I tested it out on a LG G2x and a HTC Sensation, the image is smaller on the Sensation. So is Android always just using a factor of 1.5x when calculating the size the hdpi image? Is there something I can do to guarantee the size will be the exact same on all hdpi devices? Thanks.
You can use this to help you out with the proyect
http://developer.android.com/training/multiscreen/screensizes.html
The answer was that the system does use a standard multiplier for each dpi level (1.5x for hdpi for example). In order to get around this I just used the .xdpi and .ydpi values of DisplayMetrics and do my calculations off of those real values.
Usually when ever we want to do like this we usually use wrap_content. so once try layout_width = "wrap_content",layout_height = "wrap_content". Such that ANdroid SDK will look.
Related
I understand there is plenty of documentation about designing for multiple screen support in Android. and I have read the Android guide here as well as a number of similar questions such as this
However I'm still a little confused as to how I should implement it for my application. I plan to target the following device configurations
Am I correct in thinking I will need to structure the project layouts as follows:
Medium density Normal screens HVGA 320x480 (160dpi):
res/layout-mdpi (320 x 480 )
res/layout-land-mdpi (480 x 320 )
High density Normal screens WVGA800 480x800 (x854) (240 dpi)
res/layout-hdpi (480 x 800)
res/layout-land-hdpi (800 x 480)
But what about the Medium density, large screen devices?
I plan to use sets of both high and medium density drawables too. My primary concern at this early stage is using suitable background images for each layout. For example, to support both the 480x800 and 480x854 sizes, I plan to simply use an ImageView as the background such as:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bg"
android:scaleType="center"/>
The 'bg' drawable will always be 480x854 and by using:
android:scaleType="center"
I'm hoping this will take care of those two screen sizes. Whereby the image keeps its original appearance but is centred on the 480x800 screens. I will lose some pixels off the image but as long as the image isn't scaled then that suits my needs.
I plan to have a set of 320x480 assets for the normal screens.
I'm just hoping I'm following the correct procedure here so I appreciate any info/tips from you guys. Thanks in advance
In my experience you don't really need to customize your layout for the small/medium/large/etc screens, as long as you have your drawables for the different densities. Like the documentation says, Android will attempt to render your layout properly on different screen sizes.
By default, Android resizes your application layout to fit the current device screen. In most cases, this works fine. In other cases, your UI might not look as good and might need adjustments for different screen sizes.
The 'other cases' applies only if you really want to change your layout on larger screens.
Using android:scaleType="center" works for me, but it will, like you said, leave empty space around your layout on larger screens if it should fit on smaller screens as well. If you have a fully customized view with 'widgets' that should be placed exactly right, and you don't want to be programmatically determining the scaling and applying the same scaling to your widgets, this is definitely the way to go.
I know there are many questions like this, I have read many blogs and questions on this and I am not satisfied by what I have understand.
I want to support multiple screens and resolutions like hdpi, xxxhdpi etc.
And i am using dimens.xml for this purpose. But m still unclear about how to calculate exact dp value for different screens.
For example if 48dp x 48dp ImageView is proper for hdpi device, what values should i define for xxhdpi device? Is there any fixed calulation just like there is for drawable images?
I am using these folder for trying to support multiple screens :
values-sw320dp-hdpi
values-sw320dp-xhdpi/xxhdpi/xxxhdpi
There are few problems I am facing currently
Though defining values in respective dimens.xml works almost for most of the devices, there are few devices which takes wrong values
For example I have Lg optimus G that is xhdpi device, but it reads values from values-sw320dp-xxxhdpi's dimens.xml instead of xhdpi one
I am not able to calculate the exact value for each resolution (hdpi,xhdpi etc), so the view which looks perfect in hdpi device, seems little large or small in xxxhdpi as I can't guess the value like if hdpi view size is 48dp then xxxhdpi should be of 64dp or something as I don't know the exact approach.
Also while searching for supporting different screens, I read many times about calculating dp at runtime based on density or calulating pixels etc.
I am too confused about all this. Please help me in understanding and learning the proper way of making responsive apps.
You can use resource qualifiers to specify different sizes for Views.
If you want the width of an ImageView to vary based on the size of the screen, create a new dimension in your dimens.xml file called image_view_width (for example).
This then essentially creates a copy of the dimens.xml but adding the 'Size' qualifier. This will create another version of the dimens.xmlfile, and any device that meets your specified qualifications will use that version of dimens.xml. You then add image_view_width to this new file and give it a different (smaller/bigger) value. You can do this as many times as you want and with as many different qualifiers as you want.
Finally, when you want to use this value in your layouts, you only have to type:
android:layout_width="#dimen/image_view_width"
and android will do the rest for you.
Hope this helps!
Android developers site,and most of you,Push everybody to use dp units on their layouts,
I can understand this approach if you using different layout for different densities,but when my requires is one layout.xml ,and one drawable folder,it is make no sense to me to use it,
because it is NOT preserve proportion.
It seems weird to me that there is no simple way to preserve proportion for all devices.
Just help you to understand my point.
1.make any layout with view inside it
2.set the sizes on dp as Android advise you to do
3.and then check it on the eclipse graphical view of your XML.
It looks way way different between different size devices.
Button with width of 15 dp look like 10 times bigger in 640*480 devices then Tablets.
So what's the point?
I understand all the math of conversion between dp and pixel with density,
but i looking for simple way to preserver the proportion on my layout,without define others for others densities.
The only way that i find to help is using android:weightsum,
But it can not use for margins and other settings.
Any idea?
You can always use your values folder and implements the exact dp size for each of different device densities, so you wont create different layout on different density.
Tablet and handheld devices will never have the same sizes that is where the different layout folders are created to let the developers design on different devices.
I would recommend a different layout design on tablet and handheld devices which most apps applies.
Think of dp units as referring to actual size (like cm and inches). So something that is 250dp will look (for example) about 1 inch on a phone, but also roughly 1 inch on a tablet. No matter the size and resolution of the device, it will always be about 1 inch.
Why is it done this way? Well basically it is the Android creative vision that you won't simply scale your app from a handheld screen to a tablet sized screen. This is why they don't allow you to specify heights and widths as % of screen size. The one small exception is layout_weight in LinearLayout.
You may agree or disagree with their vision, but that's the reality.
I have 2 devices, a 1024x600 7" tablet hdpi running Gingerbread and a hub attached to a touchscreen which is 1920x1008 22" in size, hdpi running ICS. The Android OS seems to consider both as "large" (240dp).
So, they have the same actual density (240dpi), same generalized density (hdpi), same generalized size (large) but different actual size (7" vs 22")
The text and spacing dimensions that I specify for my layout work great on the 22", but then on the 7" they look enormous and dont fit on the screen.
I've tried using dp and sp, no difference as I think the problem is that Android sees these things as the same size / density. Does anyone have any recommendations on how I can be able to scale sizes appropriately?
This program wil also eventually need to be supported on a 4.5" handheld as well.
Thanks in advance.
Sorry, my previous answer was completely wrong = )
Ideally, you should be able to design for the 7" tablet and have your layout scale up to the TV. But if that doesn't work you should be able to use something like layout-sw1008dp. The "sw" prefix allows you to specify the minimum dimension of the smallest side of the screen - so in the case of a TV, the height.
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.
See my stack answer which may help you.
For quite a long time, I have been declaring resource folders for 4 different densities:
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
In the layout's XML, I have been using fixed widths (while still density-independent) such as 128dp for those graphics.
However, when more and more large-screen phones, and especially tablets, were introduced, that approach did not work anymore. Although you provide density-independent resources this way, the layout will not look good on large screens.
This is why I think I need to add Dimension resources that depend on the screen size, for use in the XML layouts, e.g.:
values
values-w600dp
values-w720dp
values-w1024dp
But does that mean that I should drop supporting those 4 density containers? Or do I need to provide 16 resource folders, i.e. one for every combination of density and size?
I can't find any good help in the Android documentation as to this topic.
drawables and layouts are different. To answer your question, should you stop support those densities. Yes, but you should still support xdpi and hdpi. Romain Guy recently said that modern devices like the Nexus 7 (at a tvpi) can scale the assets properly enough that mdpi isn't really needed. And nobody uses ldpi anymore. Last I looked is was less than 2% of the market.
About layouts. A Nexus 7 (1280x800 tvdpi) would use something from the values-w1024dp but still get assets from the drawable-hdpi folder. Those two aren't mutually exclusive. Something like a S3 would also pull from the values-w1024dp but use drawable-xdpi. You only need to provide an alternative layout if your use-case calls for it.
So do you need 16 different things? No. You do need xdpi & hdpi (if not mdpi). You may want to include alternative layouts for different sizes. You can be as specific as you want or as generic. Unless you're doing a hybrid app for both phone & tablet (7 & 10 in) you probably don't need a lot of xxxx-sizexxx folders.
In the layout's XML, I have been using fixed widths (while still density-independent) such as 128dp for those graphics.
This is probably a source of your issues. Your layouts should be as fluid as possible using wrap_content and match_parent. Fixed sizes should be reserved for padding around the sides and image where you know the size ahead of time. If you do this, your layout should look decent at any size from a small 320 x 200 to a GTV size.
1) Regarding dimensions in your layouts (values/dimens.xml):
values values-w600dp values-w720dp values-w1024dp
But does that mean that I should drop supporting those 4 density
containers? Or do I need to provide 16 resource folders, i.e. one for
every combination of density and size?
No, you don't need to provide different dimensions per dpi bucket (hdpi/xhdpi), because the dimensions are already being scaled up or down based on the device (if you're using dp instead of px). So for dimensions, you only need to provide values for devices with different sizes (hence the name, values-smallest possible width-600-dp). Because you don't want 16dp padding on a phone AND 16dp on a 10" tablet as well. You'd want 64dp instead. And no, it doesn't matter what density the device has. It still needs to have the same padding on the respective device width. So for dimens, you only need to think about the device's actual physical dimensions.
2) Regarding drawables scaling for different resolutions (drawables/xdpi):
The system scales them appropriately for the device. You don't need to worry about this. Also, you don't need to add any other buckets here. Just use mdpi/hdpi/xhdpi and maybe xxhdpi because many new devices are going to use the new density in the future.
Conclusion: there are 2 different UI building components that vary according to 2 different rules: drawables based on screen density and dimensions based on screen size. Do not mistake one for the other and think you need tens of buckets in the values folder, because that's not only wrong, it's just mind boggling.