A complete solution for dips, %x/%y variants etc. Anyone please?

bluedude

Well-Known Member
Licensed User
Longtime User
Hi,

I have been looking on the forum and there are snippets of solutions but not a real clear guideline that works for all (maybe i'm not smart enough)

First of all, do I need to use the combination of dip's, %x/%y and variants on one application?

Sometimes I see dips and sometimes %x, so what is it?

Erel's guidance for creating three variants is clear. But that said, do I need to ResizeViews then with all the %x/%y stuff for every variant? Here the link that explains that: http://www.b4x.com/forum/basic4andr...25-multiple-screens-one-way-do.html#post52178

And how about dip? How does that fit into above approach and do I still need to do that. And if I use for example 100 dip for the width of a button, for which variant is that 100 dip then? I cannot set dip in the designer so I need to do that through code.

I blame Google for this problem, they should have set some standards.

Cheers,
 

thedesolatesoul

Expert
Licensed User
Longtime User
Google is partly to blame. But you cant expect the same layout to work on all resolutions/screen sizes?
After all, an app for a smartphone, and an app for a SmartTV should have a different layout.

Personally I prefer to use %x and %y because you are laying out your views etc according to the device size. (for e.g. your buttons can be 30% wide as the screen and so on)
But remember there will be a maximum/minimum limitation for this method to work.

dips come in handy, on a single layout that scales well. For e.g. from 320x240 to 640x480, you app will look fine. But any funny resolution will make it look weird.

That is just my opinion, but I am also annoyed at manufacturers coming out with random screen sizes.
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Mm, still unclear. Especially when to use dip and how in combination with x% and y%. Do I need to use both an so yes how?
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
I guess that's the problem, no universal rules :)

Do you know if you can check in code which variant the app. picked? I know we can check the device scale etc. but say for example I have three variants: 320x480, 480x800 and 800x1200 and I run this on my Galaxy Nexus. It would be nice to be able to check in code which variant it picks. I don't want to go into separate files per variant.

In above sample my Galaxy Nexus still picks 320x480.

Is it better to focus on different scales instead of resolution?
 
Upvote 0

timo

Active Member
Licensed User
Longtime User
Why don't WE invent a standard?

My idea were something like a combination of
%x/%Y with min/max ratio (x/y) and min/max %size of contained views, considering the scale as factor and a solution for textsize too (min/max size before going to second line on labels, spinners,etc)

The ratio (x/y) shoul be there for 'elegance' and once etablished, the container panel centered in the max possibility of the activity.

And then all of that 'mixture' in a library

Is that 'utopia'?

We are a lot of people with a lot of different devices. If someone propose a simple graphical app as example for elaborating this way by who wants to, then proposing his solution to test by the others, I think we could arrive at something similar to a "standard". No?
 
Last edited:
Upvote 0
U

unba1300

Guest
I haven't gotten this far with my first app yet, but it's not something I look forward to dealing with. I was basically told to just create a number of different variants and things would scale automatically, but I don't think it's that simple from the other posts I've read. I would be very happy to see a one-fits-all-apps code module that would handle this issue.
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Yeah it is a problem. When i started using B4A there wasn't a huge amount of devices/resolutions, now it is a pain.

Using resizing works but if you add a special variant for a device even that becomes more complicated. Sometimes you actually don't know which variant your app. picks from the ones you created.
 
Upvote 0

Merlot2309

Active Member
Licensed User
Longtime User
Hi,

From what I could filter until now:
- Your layout is important. eg. nice aligned Rows and Columns -> Add them in code with percentages. Text sizes depend on scales.
- Various views that have nothing in common -> Add those in the designer and resize them for various devices.

The list of device sizes that I use in the Designer and Emulator:

B4X:
'' 240x320  d1         ok         = 2.5" + 2.6" + 2.8" + 3"
'' 240x400  d1         ok         = 3.2"
'' 320x480  d1         ok         = 2.8" + 3.2" +3.5"
'' 400x800  d1         ok         = 7"
'' 480x800  d1          ok         = 5" + 7"
'' 480x800  d1.5                    ok                  = 3.2" + 3.5" + 3.7" + 4" + 4.3"
'' 576x1024 d1         ok         = 10.2" 
'' 600x800  d1         ok         = 8"
'' 600x1024 d1         ok         = 10.1"
'' 600x1024 d1.5               ok              = 7" Galaxy Tab
'' 720x1280(or 1184) d2    ok         = 4.65" Galaxy Nexus
'' 768x1024 d1         ok         = 8" + 9.7"
'' 800x1280 d1         ok         = 9.4" + 10.1"
'' 800x1280 d2         ok         = 5.3" 285dpi Galaxy Note

So, 14 in total and that should cover most of the mess.

Succes,
Helen.
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
This is a bit long winded.... sorry! :D

The GUI is definitely the biggest pain for me, not to mention time consuming. I think a lot of it does have to do with how complicated the app is and what you are showing the user.

For my (so far only) app, I was initially creating new variants every time someone would complain or I would see new specs, but as Bluedude suggests, you can't keep up with it.

I don't know that you can tell which variant the app chose to use, but I suppose it may be possible somehow. One thing I noticed is if you are trying to determine the screen height, don't use LayoutVal because it is often not the same as the actual height which can be determined by Activity.Height. I'm by no means an expert on this stuff but here are some things I have learned or chose to do during a major overhaul to my app's GUI display:

First, I decided to go with the method described here in order to come up with %x and %y values. For my app, I decided to just start over with 4 variants. 320x480, 480x320, 800x1280 and 1280x800. That is phone and 10" tablet, portrait and landscape for each. I didn't care if it looked the same on a 7" and 10" tablet, and it will look nearly identical, just larger on the 10". Doing things this way works well for many different devices but it is not perfect. I had two problems in particular:

1) Height to Width ratio differs by device using that method. While everything "fills" the screen nicely, buttons will appear stretched on certain devices. In many apps this is probably not a big deal, but my app uses images for almost all of the buttons. Anyone who has worked with images knows that you cannot change the H/W ratio without it looking funny. Perhaps 9-patch images would have worked better in my scenario but I don't know much about them. My solution was to take the height the app gave the buttons (%y) and multiply that number by the correct ratio. Even one further, for certain buttons I took the %y and %x, did the math on each with the ratio, and used the one that would produce the smaller button (if it was different). My thought was that this SHOULD ensure that there won't be a device resolution where for some reason the buttons overlap. Even with using %x and %y though, I only used the top and left positions "assigned" to just a few key buttons of the app. Using those positions, I then fit the other buttons around them using DIP, which will ensure that overall they look nearly the same on all devices.

2) By using what is essentially a single layout for all phone sizes, I noticed that on many AVDs there was a lot of dead space in between buttons and at the edges, etc. The reason for this of course is because they come in many different (higher) resolutions. The way I found to somewhat fix this problem was that when designing my base phone variant (320x480) I designed the layout very tight. Buttons as big as I could go with very little empty space. This translated to much better looking GUIs on other device sizes, but maybe a bit cramped on the default (but how many phones use a resolution that small?).

For many other screens in my app (that didn't need to be "full"), I simply created one variant (320x480) so I could get my basic layout done, then I size it all in code using DIP. Depending on the height of the screen, I sometimes make it a bit bigger to take advantage of the extra room, but mostly they are all the same size on all devices. The buttons and other views were done on panels that I "center" through code on each screen. This is one thing I *still* don't have an answer to. I chose to somewhat limit screens like this on tablets. While I could show a listview of names as wide and tall as the entire tablet, this seemed ridiculous to me. So by using DIP as mentioned above, I keep them the same size overall from device to device. If you held them next to each other, the listview would be almost the same size physically on each device. Is this right or wrong? I have no idea. But that is how I did it.

Creating variants for all of the different devices is just too much work. If you are not too picky about H/W ratios, I'd say you could probably get by with a few and just be sure to build them on a panel so that you can easily center it on the device. This is not perfect, but it would work. Honestly I think that the %x and %y thing is the way to go, but coming up with the values (by entering T, L, H & W) for all of the views on all of my screens using the Excel sheet in the linked thread took a LONG time. It would definitely be nice to have the designer capable of generating this information. But it isn't necessarily one size fits all. For some views I wanted the exact %x and %y for top, left, width and height but for others I only wanted T & L or W or H. So even the Excel sheet couldn't prevent me from having to write a lot of code to get the layouts correct.

To Bluedude: Use DIP if you want to place or size a view EXACTLY the same on each device regardless of screen size or scale. The only thing, you have to make sure it will fit on the screen. So don't use 500dip height on a 480 high screen. While you may want to use DIP for height & width (such as for an EditText), I doubt you'd want to do this for top & left. If you want views to be relatively in the same position independent of the device size / resolution, use %x and %y, but realize that spacing in between views, their sizes and H/W ratios will vary across different devices. To fix this, you can use a combination of both, which is what I did. There is a little more empty space on some devices compared to others (especially the bottom) but I feel it is negligible. This is mostly caused by my limiting the height of certain views in order to maintain the correct H/W ratio to make sure I don't accidentally make the view too big to fit when I correct the H/W ratio .

I hope this helps, and remember everyone.... you are not alone in this problem! ;)
 
Last edited:
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Kevin,

No problem, great info!

I have a few questions:

If you create these variants are you doing the math for x% and y% for all those variants (like the Excel spreadsheet)? If so, how do you handle this in code? Meaning, how do you know which variant is used by the device and which %x/%y values to use for the resizing? Do you use Activity.width for that?

Say I have a Galaxy Nexus that does not fall into one of the variants (I tested that) how do you cope with that? My Galaxy Nexus takes the 320x480 even if I provide 480x800 and 800x1200. For me that isn't the best fit.

Cheers,
 
Upvote 0

nfordbscndrd

Well-Known Member
Licensed User
Longtime User
Hi,

I have been looking on the forum and there are snippets of solutions but not a real clear guideline that works for all (maybe i'm not smart enough)

First of all, do I need to use the combination of dip's, %x/%y and variants on one application?

Sometimes I see dips and sometimes %x, so what is it?

Erel's guidance for creating three variants is clear. But that said, do I need to ResizeViews then with all the %x/%y stuff for every variant? Here the link that explains that: http://www.b4x.com/forum/basic4andr...25-multiple-screens-one-way-do.html#post52178
...

Have you looked at here and here (2 parts of the same page) in the Wiki? It discusses the problems and gives examples, screen shots, and links to examples of possible solutions.
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
Kevin,

No problem, great info!

I have a few questions:

If you create these variants are you doing the math for x% and y% for all those variants (like the Excel spreadsheet)? If so, how do you handle this in code? Meaning, how do you know which variant is used by the device and which %x/%y values to use for the resizing? Do you use Activity.width for that?

Yes. I modified the spreadsheet to accommodate the views in my app and all of the layout percentages. I have two different screens in my app that I wanted to do this for, so I have phone landscape, phone portrait, tablet landscape and tablet portrait values for each view X 2 for each of the 2 "screens". I figure out which variant it must be using by first determining if the Activity width > height or not (portrait or landscape) and then by using Activity.Height to determine whether or not it is a phone or tablet.

B4X:
Select Case Style
  Case 0 ' Compact remote
    Activity.LoadLayout ("Remote_Compact")
    If Activity.Width > Activity.Height Then ' Landscape
       If Activity.Height < 400dip Then ' Phone
         InitRemote2 ("Phone", "Comp", "Land")
           Else ' Tablet
           InitRemote2 ("Tablet", "Comp", "Land")
       End If
     Else 'Portrait
       If Activity.Height < 700dip Then ' Phone
         InitRemote2 ("Phone", "Comp", "Port")
           Else ' Tablet
           InitRemote2 ("Tablet", "Comp", "Port")
       End If
     End If
  Case 1 ..............

The sub InitRemote2 then sets the specific %x and %y values for "key" views (buttons) depending on device/orientation and then uses some generic/universal code to place many of the others, along with some specific tweaks depending on device/orientation. These %x and %y values were the results from the spreadsheet.

What got me thinking of that was something I have seen Erel say many times.... In most cases, all you need are the basic variants: Phone, 7" tablet and 10" tablet. And I always thought to myself, "Yeah, but that doesn't work!" At least not in the sense that it looks acceptable to me on all different devices. But when I considered the idea of using %x and %y and thought about the sizes of the various AVDs I have, it started to make sense. I don't know that the numbers I chose are foolproof (<400 or <700 means it is a phone), but they work for all AVDs I have tried my app on.

When I looked at the resolution divided by the "scale" on all of them I determined that in fact all of the phones were <700 high and the tablets were larger than that.


Say I have a Galaxy Nexus that does not fall into one of the variants (I tested that) how do you cope with that? My Galaxy Nexus takes the 320x480 even if I provide 480x800 and 800x1200. For me that isn't the best fit.

The only way I can think of to force a variant would be to have them in different layouts and check the activity H & W and decide yourself which one to use. But a quick question: Which Nexus do you have? I have added AVDs any time I heard about a different size and I have two that I labeled Nexus. The new one on ICS and a Nexus One. Here are the specs:

Nexus One
480x800 / scale 1.5 = 320x533.3333333333~

Nexus (ICS)
720x1184 / scale 2.0 = 360x592

So as you can see, the closest match to both of those is in fact 320x480. And remember as I mentioned above (and this was something that I could not get through my thick skull after reading it over and over here until I thought more about it)... The basic variants are:

320x480 (phone)
480x800 (7" tablet)
800x1200 (10" tablet)

And what is your nexus? Now as you know, you can create a variant with 720x1184 scale 2 and it should look perfect if that is your phone's resolution and scale. But as you also know, doing this never ends. So to me the next best thing was to use %y and %x which allows you to get closer to the look you are after without creating a new variant for every single one.

Again, I hope this helps and hopefully something will click. I don't know how many times I have read some very wise words in this forum and simply didn't get it. Maybe I still don't, but I think something clicked with these variants and I am finally starting to understand.

EDIT:

Just to add that essentially all phones will use the basic phone variant, and all 7" tablets will use the 7" tablet variant, etc. Obviously you could create a custom one in between for each device, but that is what we are trying to avoid. And when you think about it, when you create a new variant for your specific device (such as one phone to another phone), what are you mostly doing? Increasing the top, left, height and width by a certain percentage to fill it! Also, using %y for the height of views may result in some slightly off-sized views, which in the case of EditText views, this may not be ideal. In that case you can specify a dip size, such as 50dip for the height on those rather than the %y height value produced by the spreadsheet. This could technically cause overlapping some where, in which case you would have to then do some further tweaking in code.
 
Last edited:
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
Like many user on this forum I'm relatively new to both android and B4A. The app I'm currently trying to make require a fair bit of user input so lots of views to be laid out nicely. I thought it would be hard work to set all these out in 10+ variants in the designer, each with it's own little tweaks. And if any minor modifications are required in future, well, you get the picture.

So, I'm experimenting with doing the setting out in code, using %x, %y and dips. Here is a sample of my code:

B4X:
   #Region CPD Panel
   scrollChars.Panel.AddView(pnlCPD, 0, pnlSupply.Top + pnlSupply.Height + (Padding * 3), TabHostCableCalc.Width - 20dip, (spinHeight * 2) + (Padding * 3))
   pnlCPD.Color = Colors.RGB(50, 50, 50)
   
   scrollChars.Panel.AddView(lblCPDTitle, 10dip, pnlCPD.Top - 10dip, 160dip, lblHeight)
   lblCPDTitle.TextColor = Colors.White
   
   pnlCPD.AddView(lblCPDBSEN, 5dip, 10dip + (Padding * 2), 40dip, lblHeight)
   pnlCPD.AddView(spinCPDBSEN, lblCPDBSEN.Left + lblCPDBSEN.Width + 10dip, Padding * 2, 110dip, spinHeight)
   pnlCPD.AddView(lblCPDtype, spinCPDBSEN.Left + spinCPDBSEN.Width + 10dip, lblCPDBSEN.Top, 35dip, lblHeight)
   pnlCPD.AddView(spinCPDType, lblCPDtype.Left + lblCPDtype.Width + 10dip, spinCPDBSEN.Top, 75dip, spinHeight)
   pnlCPD.AddView(lblCPDRating, 5dip, 10 + spinCPDBSEN.Top + spinCPDBSEN.Height + Padding, 45dip, lblHeight)
   pnlCPD.AddView(spinCPDRating, spinCPDBSEN.Left, lblCPDRating.top - 10dip, 110dip, spinHeight)
   #End Region

I have variables called Padding, lblHeight, txtHeight, etc these will allow me to change the height of all said view type or spacing between without going through the entire code. Also, each views top and left are set in relation to the previous views on the screen. So, if I decide to change 1 view, all the others will after will adjust to match. Only tested it on a few variants, but so far seems to be going well.

One downside to this is it takes an age to do and certainly takes the 'R' out of 'RAD'. Just to point out this is not a B4A issue, it's the underlying system (Android). I see it like a sandwich. It doesn't matter what bread you use, a cheese sandwich will always be a cheese sandwich. If you don't like cheese, you don't like the sandwich. Apple maybe? :signOops:

Don't know where that came from, just popped in my head, rambling now so will wrap up.

Note: This could be completely wrong way of going about it, to which I will find out the hard way lol
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Thanks Kevin, very useful stuff! I have the Galaxy Nexus. My problem is that I like fast results and all this stuff takes RAD out of it.

Not B4A's problem anyway. Windows Phone has the anchor possibilities, that is so much easier! You can just select in the UI designer to which parts of the screen to anchor.

Another problem is of course that all these manufacturers try to be unique by providing different screen formats and resolutions. Google should takes steps to change this, just like they now do with ICS guidelines.

Cheers,
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
I feel pretty stupid, cannot get my head around it. You say you create %x/%y values for each variant and each screen? But when I look at below code you don't seem to use all these values. You say in portrait mode Height < 700, so which values are you using then? The ones from the 320x480 variant or the 480x800 variant? I mean, the %x or %y differ for these two variants.

Activity.LoadLayout ("Remote_Compact")
If Activity.Width > Activity.Height Then ' Landscape
If Activity.Height < 400dip Then ' Phone
InitRemote2 ("Phone", "Comp", "Land")
Else ' Tablet
InitRemote2 ("Tablet", "Comp", "Land")
End If
Else 'Portrait
If Activity.Height < 700dip Then ' Phone
InitRemote2 ("Phone", "Comp", "Port")
Else ' Tablet
InitRemote2 ("Tablet", "Comp", "Port")
End If
End If

One question is, why to resize if an exact variant is picked? How do you prevent that in above sample? IMO opinion it would be good to know which variant is picked by the app because if it matches a variant you don't need to do anything. Currently you cannot check this.
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
I feel pretty stupid, cannot get my head around it. You say you create %x/%y values for each variant and each screen? But when I look at below code you don't seem to use all these values. You say in portrait mode Height < 700, so which values are you using then? The ones from the 320x480 variant or the 480x800 variant? I mean, the %x or %y differ for these two variants.

Activity.LoadLayout ("Remote_Compact")
If Activity.Width > Activity.Height Then ' Landscape
If Activity.Height < 400dip Then ' Phone
InitRemote2 ("Phone", "Comp", "Land")
Else ' Tablet
InitRemote2 ("Tablet", "Comp", "Land")
End If
Else 'Portrait
If Activity.Height < 700dip Then ' Phone
InitRemote2 ("Phone", "Comp", "Port")
Else ' Tablet
InitRemote2 ("Tablet", "Comp", "Port")
End If
End If

One question is, why to resize if an exact variant is picked? How do you prevent that in above sample? IMO opinion it would be good to know which variant is picked by the app because if it matches a variant you don't need to do anything. Currently you cannot check this.

The code above that I posted is just checking orientation and whether the device is a phone or tablet. When I get home later I can post other parts.

Maybe LayoutValues is the way to go in determining which variant it used. If it works the way it sounds, maybe you can check the size or position of a specific view and compare it to a known value that you decided on at design time? If some views end up with the same values, perhaps use a special one that isn't visible but you can position in a certain spot depending on the variant? LayoutValues seemed to confuse me because I knew it wasn't the true h or w of the activity, but maybe it can be used as above. I thought it returned adjusted values based on the variant and device resolution. Still learning myself!
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
I think Layoutvalues just shows the screen dimensions of your device, it does not tell you which variant is picked from your app (unless you do variants in separate files which sucks) I mean, if you created 3 set variants you don't want to do resizeviews if an exact (say 320x480) variant is picked (so device exactly matches variant).

When I test the x% and y% stuff on a 320x480 device and use the code to resize, the button does not stay in the same place as designed in the variant of course.

Overall it isn't very bad but not very great either.

Would love to see how you implemented it in code.
 
Upvote 0
Top