Android Example Adapt your layouts using SetLayout

A code module to automatically generate SetLayout statements with percentage values.

It is more convenient to use than my example:
Create your layouts based on percentages

because all the properties that you have set in the Designer will obviously preserved, you will not have to write them in code.

[this code module is a -too fast- modification of that in that example, to save time, then it is not optimized nor "elegant"].


The process is simple, although in words it seems complicated:

a) create a layout in the Designer to test on your device/emulator (I mean it MUST be sized like your device/emulator. Do not use the standard size).

My smartphone is 480x800 scale 1.5, then:
upload_2015-9-1_1-16-53.png


b) add the module modSetLayoutsGenCode (from the project attached) to your project;
c) add this 3 lines of code after Activity.LoadLayout:
B4X:
modSetLayoutsGenCode.Init(File.DirRootExternal, Application.LabelName & ".txt")
modSetLayoutsGenCode.GeneratePercLayoutCode(Activity, "Main")
modSetLayoutsGenCode.Close
Line 1 "initializes" the code module; the two parameters will be used to write a text file with the code generated;
Line 2 generates the source code (in the example for the Activity Main);
Line 3 closes the TextWriter object (you can generate code for all your Activities, then you should call this command only after the last generation, of course).
d) run your app

You get a file with the setLayout commands (the code will also be in the Log window; in version 4.3 of B4A it will also show the lines of separation, in the version >= 5 they will not "visible"; I have to look for the reason for this :)).

Finally, copy the code generated in your project (after Activity_LoadLayout).

My layout:
upload_2015-9-1_1-33-54.png


My smartphone:
upload_2015-9-1_1-52-45.png


Code generated (Log view, b4a 4.30):
upload_2015-9-1_1-40-13.png


Test project, 10" device, 1280x800:
upload_2015-9-1_1-43-0.png


upload_2015-9-1_1-52-14.png
 

Attachments

  • upload_2015-9-1_1-32-15.png
    upload_2015-9-1_1-32-15.png
    28.7 KB · Views: 431
  • upload_2015-9-1_1-43-32.png
    upload_2015-9-1_1-43-32.png
    205.6 KB · Views: 402
  • upload_2015-9-1_1-44-8.png
    upload_2015-9-1_1-44-8.png
    103.2 KB · Views: 389
  • lm SetLayouts Gen.zip
    15 KB · Views: 548
Last edited:

incendio

Well-Known Member
Licensed User
Longtime User
On my layout, it wont work, cause, beside reposition the layout, it will also need to change TextSize & Width.
 

derez

Expert
Licensed User
Longtime User
Hi LucaMs
Thanks for the module.
I'm using something similar which resizes the views and the fontsize while running the application (instead of writing a file like your module):
B4X:
'Code module
'Subs in this code module will be accessible from all modules.
Private Sub Process_Globals
    'These global variables will be declared once when the application starts.
Private    Large, Small As Int
Private sx, sy  As Float
Public  Cf  As Float
End Sub

'Resize all the views, including those on panels, to the Device's size.
Public Sub SetSize(Act As activity, DesignLargeAxis As Int, DesignSmallAxis As Int) ', FullScreen As Boolean, Show_title As Boolean)
Dim v As View
Dim DesDiag2, RealDiag2 As Float
'Dim margin As Int = 0 ' usually each take 25 but some cases 38 or even 50.
'If FullScreen AND Show_title = False Then margin = 0
'If FullScreen = False AND Show_title = True Then margin = 50
'If FullScreen = False AND Show_title OR _
'   FullScreen         AND Show_title = False Then margin = 25

Large = DesignLargeAxis * Density
Small = DesignSmallAxis * Density

If 100%x > 100%y Then
    sx = 100%x /Large
    sy = 100%y/Small
Else
    sx = 100%x/Small
    sy = 100%y/Large
End If
DesDiag2 = Small * Small + Large * Large
RealDiag2 = 100%y * 100%y + 100%x * 100%x
Cf =  Sqrt(RealDiag2/DesDiag2)' / Density   ' font size factor

For i = 0 To Act.NumberOfViews -1
    v = Act.GetView(i)
    Modify(v)
Next
End Sub

Private Sub Modify(v As View)
v.SetLayout( v.left * sx , v.top * sy, v.width * sx ,  v.height * sy )
If v Is Button OR _
    v Is CheckBox OR _
     v Is EditText OR _
      v Is Label OR _
       v Is RadioButton OR _
        v Is Spinner OR _
         v Is ToggleButton Then
    SetFont(v)
Else
    If v Is Panel Then SetPanel(v)
End If
End Sub

Private Sub SetPanel(Vp As View)
Dim P As Panel
Dim v As View
P = Vp
For i = 0 To P.NumberOfViews -1
    v = P.GetView(i)
    Modify(v)
Next
End Sub

Private Sub SetFont(V As View)
Select GetType(V)
    Case "android.widget.Button"
        Dim B As Button
        B = V
        B.TextSize = B.TextSize * Cf
    Case "android.widget.EditText"
        Dim E As EditText
        E = V
        E.TextSize = E.TextSize * Cf
    Case "android.widget.TextView"
        Dim L As Label
        L = V
        L.TextSize = L.TextSize * Cf
    Case "android.widget.RadioButton"
        Dim R As RadioButton
        R = V
        R.TextSize = R.TextSize * Cf
    Case "android.widget.CheckBox"
        Dim C As CheckBox
        C = V
        C.TextSize = C.TextSize * Cf
    Case "anywheresoftware.b4a.objects.SpinnerWrapper$B4ASpinner"
        Dim S As Spinner
        S = V
        S.TextSize = S.TextSize * Cf
    Case "android.widget.ToggleButton"
        Dim T As ToggleButton
        T = V
        T.TextSize = T.TextSize * Cf
End Select
End Sub
 

ArminKH

Well-Known Member
if u want to stretch your layout u can simply use following code
B4X:
Sub Size
    Dim xx,yy As Double
        xx = ((100%x)/320) / Density
        yy = ((100%y)/480) / Density
        For Each View As View In Activity.GetAllViewsRecursive
            View.Width=(View.Width) * xx
            View.Left=(View.left) * xx
            View.Height=(View.Height) * yy
            View.top=(View.top) * yy
        Next
End Sub
note:at first make your layout based on 320*480 variant then comment the AutoScale in designer and then use this sub after activity.loadlayout
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
At this time perhaps I am more awake :D:
I just thought my method can not resize views added by code (then at runtime).

(Also, I have always used the Klaus' module Scale, which worked well).


Thank you for your examples, @derez and @ArminKH, I will try them.

The @ArminKH' code is obviously more compact and it seems also logical, but it ignores the TextSize.



Thank you
 

incendio

Well-Known Member
Licensed User
Longtime User
I think my layout is a bit different.

First, designed it for 10" tab with 320*480 variant. Works OK with tab s 10", but when tried on Nexus 7, layout became a mess.

What I need is to scale down from 10" display to 7" display. May be I have a design flaws, should design it first for 7" than scale up for 10".

By the way, I have tab s 10" 2560x1600, how to calculate its scale?
 

LucaMs

Expert
Licensed User
Longtime User
When you create a layout, you set its width and height, not the destination device size (10"), then I don't understand this:
First, designed it for 10" tab with 320*480 variant
Also, a tablet 10" with 320x480 exists :eek:?

The right thing to do would be to create two different layouts for different devices, large and small.
But if you want to use the same layout, I think it is better to draw it starting from medium size, not from 320x480 (too small).
 

Harris

Expert
Licensed User
Longtime User
Typically, the views will render properly - when anchored to Left, Right or Both (Top and Bottom)...
This I have learned from the Designer ...

If Hardware Suppliers had not created High-Density devices, the following issue would not exist...


It is always the TextSize (which has no Dip) that confounds me!!!
Others I have contacted state they don't have an issue with this... Wish I could learn their secret.


I have tried:

If Scale < 1.33 then
' treat scale as 1.0
Else if Scale > 1.34 AND Scale < 3.0 Then
' up the text size - generally not too bad...
Else
' this is where it blows up... scales above 3 (NEW Samsung Note 4 & 5, S 5 and 6) will never look the same as scale of 1.33 and guessing
where to set text size rarely works ...
End if

Of course, having a modern device to test on would help yet at this particular time, I cannot afford...

It does seem that the Java code has a text (dp) to render it's size - yet not exposed in B4A...

The higher the scale of the device (greater than 3.0) the more I struggle with text sizing...

Perhaps Klaus knows the magic formula to format text size based on scale... He has attempted to explain many times before but
us (no me - dim wits) don't get it.

IMO, this is the ONLY place where IOS has Android beat is since they don't have to deal with unlimited screen size and densities (scale).

I don't know if you have this issue, but 50 percent of my dev time is dealing with scaling issues.... The rest (complicated stuff) just works (easy)....

Why do I struggle? I have 5 years of B4A experience... Seems I can't get past this simple issue of device scaling (using (as advised) 320 x 480 x 1.0 (and 480 x 320 x 1.0))...



Thanks
 
Top