AutoScale Code Module

klaus

Expert
Licensed User
Longtime User
The AutoScale function in the Designer Scripts scales only views added in the Designer but not views added in the code.

To overcome this drawback I wrote a Scale Code module, the first version is already included in the Desiger Scripts & AutoScale Tutorial.

There are two other drawbacks :
  • the internal Labels of ListViews are not scaled.
  • with the Designer Scripts AutoScale function for some smartphone screen sizes especially the 480 x 800 scale 1.5 screen the scaling is not optimal (at least for me).
    With AutoScale on a screen with a resolution of 480 x 800 scale 1.5 (the standard screen is 320 x 480 scale 1) the views are stretched too much horizontally and not enough vertically because of the different width/height ratio.
I added in the Scale Module a new set of equations with two scale factors one for X and one for Y. For smartphone screens (< 6'') the views are scaled according to the screen width and the screen height without the rate factor. For bigger screens the scale factors are modified with the rate factor. For the big screens a rate value of 0 means no scaling and a value of 1 is equivalent to a scaling with %x and %y.

The AutoScale function in the code module scales also the internal views in ScrollViews, ListViews and scales the TextSize property of Spinners.

The Scale code module contains following functions:
  • Initialize Calculates the scale factors
  • SetRate(Rate) Sets a new Rate value and calculates the scale factors
  • ScaleView(View) Scales the given view with its child views
    with the new equations.
  • ScaleViewDS(View) Scales the given view with its child views
    with the Designer Scripts equations
  • ScaleAll(Activity, True) Scales all views of the given Activity or Panel
    with the new equations.
  • ScaleAllDS(Activity, True) Scales all views of the given Activity or Panel
    with the Designer Scripts equations
  • GetDivicePhysicalSize Gets the approximate physical size of the device
  • GetScaleDS Returns the Disigner Scripts scale factor
  • GetScaleX Returns the X scale factor
  • GetScaleX_L Returns the X scale landscape factor
    independant of the current orientation
  • GetScaleX_P Returns the X scale portrait factor
    independant of the current orientation
  • GetScaleY Returns the Y scale factor
  • GetScaleY_L Returns the Y scale landscape factor
    independant of the current orientation
  • GetScaleY_P Returns the Y scale portrait factor
    independant of the current orientation
  • Bottom(View) Returns the Bottom coordinate of the View
  • Right(View) Returns the Right coordinate of the View
  • HorizonzalCenter(View, x1, x2) Centres the View horizontally the view between two coordinates
  • HorizonzalCenter2(V1, V2, V3) Centres the View V1 horizontally between two views V2 and V3
  • VerticalCenter(View, x1, x2) Centres the View horizontally the view between two coordinates
  • VerticalCenter2(V1, V2, V3) Centres the View V1 horizontally between two views V2 and V3
  • IsActivity(View) Returns True if the View is an activity
  • IsPanel(View) Returns True if the View is a Panel
  • SetRight(View, xRight) Sets the Left propety of the view according to the given right coordinate xRight and the views Width property.
  • SetBottom(View, yBottom) Sets the Top propety of the view according to the given bottom coordinate yBottom and the views Height property.
  • SetLeftAndRight(View, xLeft, xRight) Sets the Left and Width properties of view View according to the xLeft and xRight coordinates.
  • SetLeftAndRight2(V1, VL, dxL, VR, dxR) Sets the Left and Width properties of view V1 between the views VL and VR with the given spaces dxL and dxR.
  • SetTopAndBottom(View, yTop, yBottom) Sets the Top and Height properties of view View according to the yTop and yBottom coordinates.
  • SetTopAndBottom2(V1, VT, dyT, VB, dyB) Sets the Top and Height properties of view V1 between the views VT and VB with the given spaces dyT and dyB.
  • SetReferenceLayout(Width, Height, Scale) sets a new layout as the reference layout, allows downscaling. AutoScaleRate has no influence in this case !
The project contains following activities showing different examples of the use of either Designer Scripts AutoScale or scaling with the Code Module.
Activities:
  • Main Main screen with an image and buttons.
  • Setup The setup screen from the GPSExample program.
  • About An about screen example.
  • DBWebView A database table in a WebView with a modified DBUtils version
    scaling the table text size.
  • DBScrollView A database table in a ScrollView.
  • Keyboard A keyboard with views added in the code.
  • ListView A ListView with the internal Labels and Bitmap scaled.
  • Calculator A calculator layout from the RPNCalc project without the functions
    scaled with the new equations.
  • Calculator1 Same as Calculator but scaled with the Designer Scripts equations.
  • Positioning Example with the different positioning routines.
Code modules:
  • Scale The scaling module
  • DBUtils The modified DBUtils module
If you run Calculator and Calculator1 on a 480 x 800 scale 1.5 device you'll see the difference between Designer Scripts scaling and the scaling with the new equations.

If you don't need all routines in the Scale module you can remove those not needed.
The Scale module scales also ScrollView2D views, if you don't use such a view you must comment the corresponding lines or remove them.

I think the code is enough self explanatory.

Best regards.

EDIT: 2013.09.27
Added SetReferenceLayout
Added HorizontalScrollView

EDIT: 2014.11.20
Amended error reported HERE.
 

Attachments

  • AutoScaleExample7.zip
    74 KB · Views: 2,328
Last edited:

klaus

Expert
Licensed User
Longtime User
The ListViews are defined in the designer, but, obviously, are "filled" by code... AFTER:) (and i know, it's logic that i MUST call Scale.ScallAll after this!)
You need to set the layouts of the ListView before Scale.ScaleAll, but you can fill and add items to the ListView afterwards.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
For me it works !
Where did you define the ListView layouts, before or after Scale.ScaleAll ?
You must define them before Scale.ScaleAll !
The attached project works on my three devices.


Now in my project I have:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("layMain")
   Activity.Title = modGlobals.gAppTitle

#Region "Listview Archivi"
   lvwArchivi.TwoLinesAndBitmap.Label.TextColor = Colors.Black
   lvwArchivi.SingleLineLayout.Label.TextColor = Colors.Black
   lvwArchivi.AddTwoLinesAndBitmap2(mTabNameMap.Get("Acquisti"), "", LoadBitmap(File.DirAssets, "MioScontrino.jpg"), "Acquisti")
' ...
#End Region

   Scale.SetReferenceLayout(480, 800, 1.5)
   Scale.ScaleAll(Activity, True)
' ...
' No other graphics statements related to lvwArchivi in the Main Activity nor elsewhere.
End Sub

And (37#) : "...I used AddTwoLinesAndBitmap2 and AddSingleLine2 in a ListView: the text does not appear in the AddSingleLine2..."

Also, I have tested your code attached (#39):
Ok, on my 480 x 800 x 1.5
but on an emulator with 480 x 600 x 1.5 the result was:

upload_2013-11-26_2-5-10.png
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
but on an emulator with 480 x 600 x 1.5 the result was:
What kind of device is this with a height of 600 ?
How did you define the Emulator.
I tested the program with an 480 x 600 x 1.5 Emulator and get the screenshot below ?!
 

Attachments

  • LayoutTestEmulator_480_800_240.jpg
    LayoutTestEmulator_480_800_240.jpg
    41.8 KB · Views: 447
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
What kind of device is this with a height of 600 ?
How did you define the Emulator.
I tested the program with an 480 x 600 x 1.5 Emulator and get the screenshot below ?!


I begin to think that everything depends on the Android SDK versions and that there is a problem between my old 480... layouts and the designer.

I wrote a few minutes ago a response to Erel:I load the project, open the designer and connect my smartphone to the designer. Immediately, without AutoScale or F5, the Abstract Designer displays views correctly but on smartphone they are streched !

Unfortunately I deleted all my emulators now. Anyway, it was one that I had created from a device definitions in the Android Virtual Device Manager, changing only the height, long time ago, just for testing.

I will do further testing tedious and inform you: to you it all works, so it's my problem :(

I thank you for your time
 
Upvote 0

joop

Active Member
Licensed User
Longtime User
I am working with the Autoscale module and it works fine,thanks for this !

But now I tried to use it with a xml file for setting the cursor color for an EditText view .
and it gives an error .

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to anywheresoftware.b4a.BALayout$LayoutParams on the Autoscale module

Without the Autoscale module it works ok
With the designer Autoscale it works ok

Is it posibble to use a layout xml file and a layout bal file in combination with
the Autoscale module ?


Activity, layout1 xml file in \Objects\res\layout

B4X:
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:orientation="vertical" >

<EditText android:id="@+id/String_EditText1"
          android:layout_height="30dip"
          android:layout_width="300dip"
          android:textColor="#000000"
          android:textCursorDrawable="@null">

</EditText>

</LinearLayout>


An example is attached
 

Attachments

  • Cursor.zip
    80.4 KB · Views: 427
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
B4A doesn't recognize the Left nor the Top property !?
If you put one of these lines in the code you get the same error.
String_EditText1.Top = 30dip
String_EditText1.Left = 30dip


Why this happens is beyond my knowledge, Erel should have a look at it.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Change your XML to:
B4X:
<?xml version="1.0" encoding="utf-8"?>


<EditText xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/String_EditText1"
  android:layout_height="30dip"
  android:layout_width="300dip"
  android:textColor="#000000"
  android:textCursorDrawable="@null">

</EditText>

Add the layout to a panel and then take the EditText from the panel and add it to the activity:
B4X:
Dim x As XmlLayoutBuilder
Dim p As Panel
p.Initialize("")
x.LoadXmlLayout(p, "layout1")
Dim et As EditText = p.GetView(0)
et.RemoveView
Activity.AddView(et, 0, 0, 200dip, 200dip)
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
ListViewX.TwoLinesLayout.Label.Height = 40dip changes all items or only the next added?

It changes the Label-HEIGHT of the UPPER Label of ALL two-line-items (without Bitmap) to 40dip

Maybe you have to change an other layout? Possibly you wanted to use

B4X:
lv.TwoLinesAndBitmap.Label.Height = 40dip
?
 
Upvote 0

jairbj

Member
Licensed User
Longtime User
Change your XML to:
B4X:
<?xml version="1.0" encoding="utf-8"?>


<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/String_EditText1"
  android:layout_height="30dip"
  android:layout_width="300dip"
  android:textColor="#000000"
  android:textCursorDrawable="@null">

</EditText>

Add the layout to a panel and then take the EditText from the panel and add it to the activity:
B4X:
Dim x As XmlLayoutBuilder
Dim p As Panel
p.Initialize("")
x.LoadXmlLayout(p, "layout1")
Dim et As EditText = p.GetView(0)
et.RemoveView
Activity.AddView(et, 0, 0, 200dip, 200dip)

Hi EREL, there is a way to use together the xmllayout and the designer file?
I only want to add "android:textCursorDrawable="@null">" to my already defined and positioned edittext trough layout editor.
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
Hello Klaus
I am trying to use your stairs module into an activity that uses StdViewPager to create tabbed.
With this view, it does not work resizing of controls.
Here are some of the codes.
Can you help me please

B4X:
Private vp    As StdViewPager

Scale.SetRate(0.5, True, True)

Dim height As Int             = 100%y * 2.5 
vp.Initialize("vp", 3, 100%x, height)
Activity.AddView(vp.AsView, 0, 0, 100%x, height)

vp.Panels(0).AddView(msvDatiTicket, 0,0, 100%x, 100%y)
msvDatiTicket.Panel.LoadLayout("frmInterventiDatiTicket")

Scale.ScaleAll(Activity, True)


Thanks
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I have never used the StdViewPager.

What exactly doesn't work ?

Which version of the AutoScale module do you use ?
In my module, version 1.4, Scale.SetRate has only one parameter, not three.

You use %x and %y values, this will not work with the Scale module because it will rescale

I am estonished with this Activity.AddView(vp.AsView, 0, 0, 100%x, height), where height = 100%y * 2.5.
Why is the height 2,5 times the screen height ?
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
Hello Klaus
you think you can integrate Std ViewPager?
It does not work resizing of controls. I put log in ScaleView function and it seems that there are no controls?
I enclose the scale form that I downloaded from the forum.
Screen height is 2.5 because I do vertical scrolling with the keyboard displayed.
Thank you
 

Attachments

  • Scale.bas
    22.8 KB · Views: 380
Last edited:
Upvote 0
Top