Multiple screens - one way to do it

dlfallen

Active Member
Licensed User
Longtime User
There have been several posts regarding designing layouts for multiple screen sizes and densities. Specifying view locations in terms of %X and %Y is one such approach which will adapt to any screen. The result may not be optimized visually, but at least it should work on any device.

For most projects, I use the visual designer to layout the various views. Converting multiple views to relative positions can be quite tedious, but here is one method to speed the process (I used this method to update my ProbCalc program located in the Share Your Creations forum):

I used the visual designer to layout all of the views (I used 320 x 480 scale=1).

In Excel (or similar spreadsheet) I created a row with 5 columns containing "Name L T W H".

I then entered the name of each view along with its L T W H values.

I then added 4 more columns labeled "X Y X Y".

For each row (view) I had Excel divide each view's layout values by either X (320) or Y (480) (multiplied by 100 to yield the relative percentages).

Then using Excel's Concatenate fuction I generated the appropriate SetLayout string for each view.

Finally, I pasted these strings into my program in a sub called "ResizeViews", which is called from the sub Activity_Resume.

Because I wanted different portrait and landscape views, I repeated the process for the alternate layout.

It sounds a lot more complicated and time consuming than it really was. Inspect the attached spreadsheet and I think you will see.
 

Attachments

  • Android.zip
    7.3 KB · Views: 1,041

mjtaryan

Active Member
Licensed User
Longtime User
This may be a dumb idea, but isn't there a way to do this adjusting mathematically from within the app? What I'm thinking of is an initial layout where the resolution and density is known and where the positions and sizes of the objects are known in relation to this initial layout. Then being able to determine the actual resolution and density of the actual device and calculate the positions and sizes of the objects as a ratio between the initial layout and the actual layout. Or am I oversimplifying?
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
This may be a dumb idea, but isn't there a way to do this adjusting mathematically from within the app? What I'm thinking of is an initial layout where the resolution and density is known and where the positions and sizes of the objects are known in relation to this initial layout. Then being able to determine the actual resolution and density of the actual device and calculate the positions and sizes of the objects as a ratio between the initial layout and the actual layout. Or am I oversimplifying?
Not a bad idea at all. Actually this thing has been covered, you can search in the forum, there are posts available, you can even find Erel's solution to this problem. Of course, you can deal with relative positioning, after all, this is what %x and %y used for in views' dimensioning.
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
Replacing spreadsheet by code in the app

This seemed like a good idea. So I tried some coding for this. I expected ButtonView.Left (where ButtonView is a button's name) to provide me with the number 100 (i.e. the value given by B4A's Designer in the Left property for that button). However, it actually provided 225. The Designer has only one layout variant: 320x480scale=1(160dpi). Can anybody explain why this is?
 
Upvote 0

mjtaryan

Active Member
Licensed User
Longtime User
Is there a way to read a device's resolution and ppi? Also, I seem to remember reading somewhere in the documentation or the forums a "formula" for determining the density, but the memory is rather vague -- it has been roughly a year since I saw that. Where might it be?
 
Upvote 0

mjtaryan

Active Member
Licensed User
Longtime User
Thanks. That will help. But again, is there a way to read the Height X Width resolution and the pixels per inch from the device itself?
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
Improving dlfallen's spreadsheet method

I'm trying to improve dlfallen's method by replacing use of a spreadsheet with code based on extracting a view's left,top,width,height and then calculating new values for these which are then plugged into the SetLayout command. However, these extracted values are not what I expect. I have 2 layout variants: both for 320x480density1.0 device - one for portrait & one for landscape. When I link to an emulator with 480x800density1.5 in portrait mode, the resultant app senses portrait correctly (using comparison of Activity.Width * Activity.Height) but gives strange values using ButtonView.Left property etc (ButtonView is the name of a particular button view). I set ButtonView in the Designer to have 110,340,120,60 (for left,top,width,height correspondingly). I actually get (using Log statements for ButtonView.Left property etc): 165,566,180,100. I half expected to see 165,510,180,90 (i.e. original values multiplied by 1.5). Please explain why these values occur & how I can obtain the initial values that I set in the Designer.
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
Improving dlfallen's spreadsheet method

Re my previous post on this topic: what 'Android' seems to do is recalculate (at runtime) the position & size of a view according to the device's characteristics but 'optimises' them in some way such as using the same actual/variant ratio for both vertical & horizontal. Thus, the Left/Top/Width/Height properties are changed at runtime. This makes it difficult to replace the spreadsheet by B4A coding. So I've given up on dispensing with the spreadsheet.

I have another question. I have a layout with a number of views on it. Using the designer, some of the adjacent views have no space between them. This results in some of the views overlapping each other when ResizeViews is executed. Would this cause problems as I have LabelInformation view (created by code) in ScrollViewInformation view which overlaps with ImagePhoto view (the LabelInformation view being used to vertically scroll long text)? My guess is that the coding in ResizeViews needs to incorporate rounding to the nearest integer. Is that correct?

Spreadsheet showing L,T,W,H values:
ScrollViewInformation 0 120 210 200
ImageViewPhoto 0 320 210 160

ResizeViews (for 360x480 variant i.e. Portrait layout in the spreadsheet) extract:
B4X:
ScrollViewInformation.SetLayout(0%X,25%Y,65.625%X,41.6666666666667%Y)
ImageViewPhoto.SetLayout(0%X,66.6666666666667%Y,65.625%X,33.3333333333333%Y)

Using appropriate Log statements (to show Left,Top,Width,Height) this resulted at runtime in:
ScrollViewInformation(0,120,210,200)
ImageViewPhoto(0,319,210,159)

If I'm correct, what is the best way to incorporate coding in ResizeViews?
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Re my previous post on this topic: what 'Android' seems to do is recalculate (at runtime) the position & size of a view according to the device's characteristics but 'optimises' them in some way such as using the same actual/variant ratio for both vertical & horizontal. Thus, the Left/Top/Width/Height properties are changed at runtime. This makes it difficult to replace the spreadsheet by B4A coding. So I've given up on dispensing with the spreadsheet.

:confused:

I have many complex layouts resizing perfectly with various screen sizes (one of them shows a grid, can be zoomed and needs to be pixel-precise). So I think I can help but I hardly figure out the problems encountered.
In the designer, if you set your views this way (using a script):
B4X:
View1.Left = 10dip
View1.Width = 200dip
View2.Left = View1.Left + View1.Width
View2.Width = 200dip
They are adjacents and will never overlap. With any resolution or density.
Same thing if you use percents:
B4X:
View1.Left = 5%x
View1.Width = 50%x
View2.Left = View1.Left + View1.Width
View2.Width = 40%x
In a layout, you should never use any other units than dip or percent.
 
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Another advice:
Since the dip value is rounded while it is converted to pixels, you should never add dips yourself. 13dip+17dip is not the same as 30dip because of the roundings. That's why you can find in my code things like 8dip+(2*25dip).
 
Last edited:
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
There have been several posts regarding designing layouts for multiple screen sizes and densities. Specifying view locations in terms of %X and %Y is one such approach which will adapt to any screen. The result may not be optimized visually, but at least it should work on any device.

For most projects, I use the visual designer to layout the various views. Converting multiple views to relative positions can be quite tedious, but here is one method to speed the process (I used this method to update my ProbCalc program located in the Share Your Creations forum):

I used the visual designer to layout all of the views (I used 320 x 480 scale=1).

In Excel (or similar spreadsheet) I created a row with 5 columns containing "Name L T W H".

I then entered the name of each view along with its L T W H values.

I then added 4 more columns labeled "X Y X Y".

For each row (view) I had Excel divide each view's layout values by either X (320) or Y (480) (multiplied by 100 to yield the relative percentages).

Then using Excel's Concatenate fuction I generated the appropriate SetLayout string for each view.

Finally, I pasted these strings into my program in a sub called "ResizeViews", which is called from the sub Activity_Resume.

Because I wanted different portrait and landscape views, I repeated the process for the alternate layout.

It sounds a lot more complicated and time consuming than it really was. Inspect the attached spreadsheet and I think you will see.
There have been several posts regarding designing layouts for multiple screen sizes and densities. Specifying view locations in terms of %X and %Y is one such approach which will adapt to any screen. The result may not be optimized visually, but at least it should work on any device.

For most projects, I use the visual designer to layout the various views. Converting multiple views to relative positions can be quite tedious, but here is one method to speed the process (I used this method to update my ProbCalc program located in the Share Your Creations forum):

I used the visual designer to layout all of the views (I used 320 x 480 scale=1).

In Excel (or similar spreadsheet) I created a row with 5 columns containing "Name L T W H".

I then entered the name of each view along with its L T W H values.

I then added 4 more columns labeled "X Y X Y".

For each row (view) I had Excel divide each view's layout values by either X (320) or Y (480) (multiplied by 100 to yield the relative percentages).

Then using Excel's Concatenate fuction I generated the appropriate SetLayout string for each view.

Finally, I pasted these strings into my program in a sub called "ResizeViews", which is called from the sub Activity_Resume.

Because I wanted different portrait and landscape views, I repeated the process for the alternate layout.

It sounds a lot more complicated and time consuming than it really was. Inspect the attached spreadsheet and I think you will see.

I just searched the 'Share your creations' forum to find your posting about your Probcalc app. However, the search did not show it and I didn't want to go through all 32 pages of that forum. So I'm posting queries about the app here. I wanted to find out chi square values for df=1. So I clicked on the Chi Sq radio button, entered 1 in the df box & clicked Calc Chi Square: nothing happened. I've done the same again but entered values of 1,5,90 & 95 in the Alpha box: but I get a popup saying 'bad arguments in gammq each time followed by a popup saying x<0 in gser. What is Alpha & what am I doing wrong? Could it be that I'm using an old version of Probcalc with a bug in it? Android's Manage Apps does not show a version number.
 
Last edited:
Upvote 0
Top