Android Tutorial Supporting multiple screens - tips and best practices

Status
Not open for further replies.

GuyBooth

Active Member
Licensed User
Longtime User
What am I missing?

I have read through the threads and tutorials on multiple device setups, but have not been able to get past a basic problem.
I built my app based on an S3, using layouts in the designer, without any scripts. It is portrait only, looks good in the emulator (320 x 480) and on my S3.
Firstly, As soon as I uncomment the AutoScaleAll, the layout "Jumps", and I lose the small amount of padding I had included on the right hand side. The only way I have found to get it back is to add the line "AutoScaleRate(0.0)". No other value will get it back.
Secondly, I added a Variant for a 10.1 tablet, portrait mode. When I apply the layout to this variant, the layout only takes up about 1/4 of the screen. To fill the screen I have to set the AutoScaleRate to 0.75. But if I set it to 0.75, the S3 layout is wrong.

This doesn't match anything I've read. This is just a simple panel layout, there's nothing extraordinary about it. Everyone else seems happy with it, so I must be doing something wrong? Or am I not understanding what it is designed to do? I can put the scaling into the device specific scripts, but I didn't think it belonged there.
 

andrewtheart

Member
Licensed User
Longtime User
Hi Erel:

How do I access AutoScaleAll and AutoScale? They are not recognised by the IDE.

Sorry if I should have opened a different thread for this, but it seems relevant to this guide.
 

LucaMs

Expert
Licensed User
Longtime User


I start to think about being obtuse, but just do not understand (especially I do not understand why the layout that I made some time ago do not fit any display).

And I had good grades in geometry, ever since elementary school!

But all the "work" should not be resolved by simple linear equations?

Button1.Height(50dip) : Button1.NewHeight(Xdip) = Screen.Height(480dip) : Screen.NewHeight(960dip)

then: Button1.NewHeigh(Xdip) = (Button1.Height(50dip) * Screen.NewHeight(960dip)) / Screen.Height(480dip)

then: (50dip * 960dip) / 480dip = 100dip!

What the hell does "AutoScaleRate - Sets the scale rate. This is a number between 0 to 1. The default value is 0.3." ... is it a random number?

Sorry for my nerves and my bad English.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
But all the "work" should not be resolved by simple linear equations?
No. The purpose of AutoScaleAll is not to "stretch" the layout. If you set the scale rate to 1 then it will just stretch the layout (more or less).

AutoScaleAll slightly increases (or decreases) the size of all views, and the text size of all views. You can see how AutoScaleAll works in Klaus AutoScale code module.
 

LucaMs

Expert
Licensed User
Longtime User


I'm afraid it's because of my poor English.

The purpose of AutoScaleAll is or is not to obtain the same proportions of views on any display?

Ie: my device is 480x800, buttonX is 50x100 and by means of AutoScale you want to get that on a display of 240x400 buttonX automatically become 25x50 (taking into account also the factor dpi)?

If not, I really do not understand. If so, I do not understand the functionality of AutoScaleRate: perhaps to decrease or increase the size and not to make them "compatible"?

I will study carefully the Klaus module, but at first glance, it seems to do the same work than one i tried to develope, without getting the results that I wanted (although it seemed to work with B4A 1.80).

Thank you for trying to explain it to me, Erel.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The purpose of AutoScaleAll is or is not to obtain the same proportions of views on any display?
No. The tablet layout should not look like the an enlarged phone layout. If you do want to create such a layout then you should set all the dimensions with %x and %y.

my device is 480x800
480x800 is meaningless without the device scale. I guess that the scale is 1.5. In that case the phone "normalized" layout is 320x533, scale=1.0. This means that it is a bit taller than the standard layout of 320x480, scale=1.0.

AutoScaleAll works correctly. I recommend you to use the UI Cloud and run some tests to better understand what it supposed to do.
 

corwin42

Expert
Licensed User
Longtime User
I think there is many confusion about what AutoScaleAll really does. AutoScaleAll has nothing to do with scaling the same layout to different display resolutions and sizes. This is done automatically by Android with the scale factor of the display. But because of different aspect ratios of the displays you will have to position the elements with the help of %x and %y values.

The only thing AutoScaleAll does is make the elements (buttons etc) on a tablet slightly larger than on a phone to make them look better. Nothing else.
 

LucaMs

Expert
Licensed User
Longtime User

I'll try to use x but I guess that's how to do testing on emulators

thanks

PS expand to read all, please
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User


"This is done automatically by Android with the scale factor of the display. But because of different aspect ratios of the displays you will have to position the elements with the help of %x and %y values."

You mean that my views on 480x800-1.5 automatically (S.O.) would be perfect on a 240x400-1.5? But even that (aspect-ratio) if the second display was 200x400-1.5, using % should already fit everything, all kinds of views and texts! If so, because I would need to... "...slightly larger..." ?

I give up. I'll never understand. Maybe writing less and doing more tests.

Many thanks all
 

LucaMs

Expert
Licensed User
Longtime User
I use 2 layouts in this project (is a test). The first is used only as Main to launch the second one, but:

layMainTest1 (NEW) built using b4a 3.00 - 480x800(1.5) (NOT "normalized")
layRicordami (OLD) built using b4a 1.80 - 480x800(1.5) (NOT normalization, obv.)

MY STEPS:

load project
open the designer
load "layMainTest1"
load "layRicordami"
select (try to load) "layMainTest1" - msg : "Do you want to save designer changes?"
but i changed nothing!
That message does not appears when i load "layRicordami" having layMainTest1 loaded.
I answered NO

Running only the (empty) scripts in the Designer:

Without AutoScaleAll "actived", nothing changes. Activing it, both layouts appear stretched (on the Abstract Designer)


Running project:
on my device (480x800-[240] S.O. 4.0.4:

Without AutoScaleAll the layout appears vertically stretched: WHY?

Using instead:
Scale.SetReferenceLayout(480, 800, 1.5)
Scale.ScaleAll(Activity, True)
Texts are wrong or disappeared. Adding Scale.SetRate(1) too.
[UPDATED] Klaus, a strange thing happens.

The contents of the listview seems to disappear but I launched the program with debugging, and if I keep pressing F8 until the end of scaleall ... this does not happen, the listview is ok.

Maybe you should put an .Invalidated somewhere? But why this happens at 480x800... and not 480x640?




on an emulator: 480x640-[160] API L.19:

Scale.SetReferenceLayout(480, 800, 1.5)
Scale.ScaleAll(Activity, True)
Texts are right.
 

Attachments

  • lm Test1.zip
    13.4 KB · Views: 556
Last edited:

klaus

Expert
Licensed User
Longtime User
Using instead:
Scale.SetReferenceLayout(480, 800, 1.5)
Scale.ScaleAll(Activity, True)
Texts are wrong or disappeared. Adding Scale.SetRate(1) too.
Sorry, there is an error in the Scale module when Width or Height properties are lass than 0.
I wasn't aware that the default values for the Label Width and Height in a ListView are -1.

Try the attached amended version.
Scale module version 1.4
 

Attachments

  • lm Test2.zip
    13.4 KB · Views: 569

LucaMs

Expert
Licensed User
Longtime User
Klaus, a strange thing happens.

The contents of the listview seems to disappear but I launched the program with debugging, and if I keep pressing F8 until the end of scaleall ... this does not happen, the listview is ok.

Maybe you should put a. Invalidated somewhere?
Sorry, there is an error in the Scale module when Width or Height properties are lass than 0.
I wasn't aware that the default values for the Label Width and Height in a ListView are -1.

Try the attached amended version.
Scale module version 1.4



LOL

I was writing...

SOLVED:

Else If GetType(v) = "anywheresoftware.b4a.objects.ListViewWrapper$SimpleListView" Then
' test if the view is a ListView
' if yes scales the internal views
Dim ltv As ListView
ltv = v
DoEvents <--- WITH THIS
 

LucaMs

Expert
Licensed User
Longtime User
Sorry, there is an error in the Scale module when Width or Height properties are lass than 0.
I wasn't aware that the default values for the Label Width and Height in a ListView are -1.

Try the attached amended version.
Scale module version 1.4


Both solutions work, but my is empirical, your is technical. Now I have no way to understand it, my head smokes (ehm that is, it gives off smoke)

Thanks
 

LucaMs

Expert
Licensed User
Longtime User
Sorry, there is an error in the Scale module when Width or Height properties are lass than 0.
I wasn't aware that the default values for the Label Width and Height in a ListView are -1.

Try the attached amended version.
Scale module version 1.4


As I wrote in a post, I had also developed a module like yours.
It's not bad, but do not fit the images, I have not studied them enough.

But the biggest problem is in TextSize.

You multiply by cScaleX, I did it (instinctively!) for a factor Y.

Still in the project lmTest1, I have tried both and also their average, on a 480x600-240 emulator,
but none of the three solutions is optimal. X, for that display, is the worse.

I'll start studying typography ... I MUST find the solution

(If I can afford a few tips (useful for all of us ) ...
You could optimize the code with Scale.ScaleAll (Activity, ScaleMode, True)?
Use a variable instead of calling GetType always.
I do not allow myself to edit your useful module)


Best regards
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…