I've been trying to get a universal layout working on Android with no success. My understanding is that if you specify all widgets in dp, and make it look right in one screen size, it should scale properly to other resolutions, but my results look kinda wrong to me.
I layed out everything in HVGA using a relative layout. The relative layout has a background that our UI designer used to define element boundaries. In this layout, everything looks perfect.
Then I switch to a larger screen with a slightly different aspect ratios, the background scales properly but everything else looks off by some dp. My question is, what is the golden way to make all the elements scale correctly with screen. I want to preserve the ratios of all the elements with respect to the background.
Thanks!
Edit: figured out how to do this. The reason for inconsistency between buttons and background is that background is scaled differently from dp, and devices apparently have different dps. The solution is to manually compute the scale factor from absolute pixels then scale everything manually by that factor. Here is a good reference how to do this:
Scale Android for different screens
dp scales itself in such a manner so that the size of any widget remains constant on different screens having different resolution.
In your case, the size of list-view remains constant but the background stretched to the screen width. To avoid this, use first colour as background of first list-view and same as for second list-view.
Related
This might be a dumb question but I'm using unity to build a double pendulum app and because not all screen sizes are the same the UI buttons get moved around and don't scale to match the phones screen size. I attached a few images to show you what I mean.
Notice how in the third image, the return button overlaps the other UI sliders. I think the issue is that the pixel distance from the top of the screen doesn't change given new orientation. Is there a way to keep the spacing proportional?
On your canvas object, set it to Scale With Screen Size then, set the Match property to 0.5. This way the canvas will scale with both width and screen height.
If you need more info about Designing UI for Multiple Resolutions, check here
Well in your parent cancas object in the inspector,the 2end setting there a a drop down. Click it than a magical setting scale with screen wil be ther.👍
On Gideros I set the Logical Dimensions to 720x1080, with Scale Mode = Letterbox, and when I test it on the emulator with the same resolution it looks good, with no bars at the top and bottom or at the sides.
Then when I test it on a Sony Xperia T (720x1080 also) it shows a top and bottom black bar, with the navigation bar at the right side. It seems as if the navigation bar was interfering with the game's width, and so it loses width so the game will fit, ending up with the mentioned top and bottom black bars. Am I right? is that why I get those bars?
The problem also happens when I set the game's Logical Dimensions to 480x800 and change the images for that resolution. On the emulator works fine but on a 480x800 device it shows the same bars.
So my question is: Why am I geting the top and bottom black bars on my devices? Is it because of the navigation bar? How could I fix this?
PD: The game is on Landscape mode
Yes you are right
since onscreen "hardware" buttons does not count as part of the screen, the width then is smaller, thus you get the spaces.
(BTW you can change portrait to landscape in AndroidManifest to display buttons correctly)
More information on spaces and scaling
So you have a logical dimensions, for example: 480w by 320h (although they should be vice versa 320x480, (in logical dimension smaller always comes first) but thats another topic)
It means all your content must be prepared to deal with this dimensions.
But hey, not all devices have this dimensions right, so how to make it look similar on 800x480? You scale it up.
If the aspect ratio is the same (which is not the case in this situation as (480/320 = 1.5) and (800/480 = 1.66)) then you could simply scale up the scene with the one value for both width and height
But what if the aspect ratio is different
There are 3 ways to deal with it:
1) Stretching
We could stretch your width or height (what ever's ratio is larger) to fit the whole screen.
2) Cropping
scale by center to fill whole screen and crop out other what goes outside the screen
may not fit everyone but someone may use it.
3) Letterbox
It upscales to the maximal dimension of width or height, which fills the screen first, leaving whitespaces on other dimension.
What you choose depends on what you need to achieve, but my preference is Letterbox
And my suggestion would be, to prepare bigger BG graphics that go outside the screen (positioning them in the center of the screen using anchorpoint) and concentrate all the game on your logical dimensions.
Here's an example:
http://giderosmobile.com/forum/discussion/comment/13692#Comment_13692
Work with desktop simulator set with your logical dimensions if what is better for your, and change resolutions of the Desktop player to see how spaces appear and what BG pics may cover it
Another confusion may be, that by scaling in center, 0,0 coordinate is not in the left top position anymore (thus having spaces)
So what if I want to position object in the corner completely
Then as you did, ignore scaling by calculating the real offsets
http://appcodingeasy.com/Gideros-Mobile/Ignore-Automatic-Screen-Scaling-when-positioning-objects
Hope that helps :)
I've tried as many permutations of scaleType and fillViewport and adjustViewBounds and layout_* as I can think of and none of them do what I want. They either fill the screen but lose the aspect ration (fillXY), cut off a portion of the image (centerCrop), or scale the image down so it doesn't fill the width of the screen (centerInside, fitStart, fitCenter, center, matrix).
Here is one specific example:
Source image is 222x470 pixels.
Emulator screen is 480x800hdpi in portrait orientation.
I want the ScrollView to fill the entire screen.
I want the ImageView to scale the image so it fills the width of the screen (stretching the source image from 222 wide to 480 wide).
I want the ImageView to preserve the aspect ratio of the source image, meaning its height will have to scale from 470 pixels to approximately 1016 pixels.
Since that won't fit on the screen (it is only 800 pixels high), the ScrollView should kick in. By default the top of the image should show and the ScrollView should allow scrolling down to see the rest of the image.
This is just one example. Ideally I'd like this to work regardless of image size and screen size.
Extra credit if you know a way to do it all within the XML layout.
And before y'all come down on me like a ton of bricks (or bricked cellphones?), I'm aware there are several similar questions on this site (see here, here, here, here, and here) but they are either unanswered or the answers are unacceptable ("use fitXY", which does not preserve aspect ratio, or require specifying exact pixel width/height in the ImageView which is not a general purpose solution to the problem). It'd be nice to get a solid answer to this documented and out there.
Answering my own question in the hopes it helps someone else.
I found a simple functional answer here. The AspectRatioImageView class works where all my XML scaling attempts failed.
I have a FrameLayout that is used to display a camera feed for scanning with ZBar.
I would like it to take up a large proportion of every screen the app runs on. A hardcoded 275dp square looks great on the latest phones but pushed stuff off when for smaller screens.
I am planning on hardcoding a 175dp square and then in code making it grow based on the dimensions of the phones screen.
I'll probably do a switch on various screen sizes and then decide what to resize the frame to.
Is this a good approach?
How would I go about doing this in XML?
A LinearLayout with layout_weight specified for height/width will allow you to simulate a percentage based layout, otherwise you can use fill_parent when you want to use the whole screen width/height.
You can make one xml layout file for ldpi, mdpi and hdpi(xhdpi and tvdpi if you want to) and literally set different xmls according to the screensize. With this you will be able to fit most screens without a problem, but it is not as accurate as percentage. But remember that not all android devices has the usual 16:9 or 16:10(8:5) and therefore percentage may make the square a bit different from screen to screen.
You can make your own layout qualifyers, but the standard ones are in most cases more then enough.
You should also consider makeing only the frame layout in java, and the rest of the layout in xml.
Is it a bad habit to get the width and hight of the device and set images/button sizes programmatically accordingly.
I find it inaccurate to use different folders for layouts and densities as it gives me wierd results on some devices (on top of the inacurancies)
Your experience is appreciated.
Thank you
Yes it is very wired thing to make the layout for the all supported screen of android. And there are lots of screen resolution available in market.
Once i have made a Demo and it Works for me. I have made one Button which height and Width is same. Now i have set its required height and width as per the one Screen in which it is looking perfect.
After that i have calculated the pixel that it required to make it Possible in that screen and based on that i have applied it to all screen.
Now it works great in all device with any density and resolution.
So if there is any view that generate at run time and you want to set its height and width then the best way is to calculate its height-width ratio and use it.
hope it will helps you.
Enjoy Coding. . . .
:)
Well, most of cases you will have layouts which are, or will become, complex, and it will be difficult to calculate the positions programmatically.
And it will be also a disadvantage mantaining it, because you will not be able to use the interface stuff (grafic layout and so on), and other people, or yourself, will not understand the calculations the same way they would if they see the views in XML. Reorganizing, changing somewhere a position could be painful.
You also will be working frequently with bitmaps, which have a fixed size, if you calculate the dimensions programmatically and stretch they will not look good. At least you would need different set of bitmaps and load accordingly.
It helps if you for example use relative layouts with rules (like above of / align at the bottom of the parent, etc), linear layouts with weights, and dip (density independent pixels). You should do programmatic layout only when it's not possible in other way. Or in some certain cases where it really-really makes things easier.