Android Tutorial Designer Scripts Tutorial

Background

One of the most common issues that Android developers face is the need to adopt the user interface to devices with different screen sizes.
As described in the visual designer tutorial, you can create multiple layout variants to match different screens.
However it is not feasible nor recommended to create many layout variants.

Basic4android v1.9 introduces a new tool named "designer scripts" that will help you fine tune your layout and easily adjust it to different screens and resolutions.

The idea is to combine the usefulness of the visual designer with the flexibility and power of programming code.

You can write a simple script to adjust the layout based on the dimensions of the current device and immediately see the results. No need to compile and install the full program each time.

You can also immediately see the results on the abstract designer. This allows you to test your layout on many different screen sizes.

How to

Every layout file can include script code. The script is written inside the visual designer under the new Designer Scripts tab:

SS-2012-03-20_12.55.44.png


Their are two types of scripts: the general script that will be applied to all variants, and a script specific to the current variant.

Once you press on the Run Script button (or F5), the script is executed and the connected device / emulator and abstract designer will show the updated layout.

The same thing happens when you run your compiled program. The (now compiled) script is executed after the layout is loaded.

The general script is first executed followed by the variant specific script.

The script language is very simple and is optimized for managing the layout.

Lets start with an example.

Example

In this example we will build the following layout:
SS-2012-03-20_13.08.05.png


btnLeft and btnRight should be located in the top corners.
btnDown should be located at the bottom and fill the entire width.
ListView1 should fill the entire available area.
ToggleButton1 should be located exactly in the center.

The first step is to add the views and position them with the visual designer (you do not need to be 100% accurate).
Now we will select the designer scripts tab and add the code.
Note that the views are locked when the designer scripts tab is selected.

The code in this case is:
B4X:
'All variants script
btnRight.Right = 100%x

btnDown.Bottom = 100%y
btnDown.Width = 100%x

EditText1.Width = 100%x
EditText1.Bottom = btnDown.Top - 5dip

ListView1.Width = 100%x
ListView1.SetTopAndBottom(btnLeft.Bottom, EditText1.Top)

ToggleButton1.HorizontalCenter = 50%x
ToggleButton1.VerticalCenter = 50%y

The result:

SS-2012-03-20_15.10.06.png


10'' tablet:
SS-2012-03-20_15.11.16.png


SS-2012-03-20_15.35.16.png


Reference

The following properties are supported:

- Left / Right / Top / Bottom / HorizontalCenter / VerticalCenter - Gets or sets the view's position. The view's width or height will not be changed.

- Width / Height - Gets or Sets the view's width or height.

- TextSize - Gets or sets the text size. You should not used 'dip' units with this value as it is already measured in physical units.

- Text - Gets or sets the view's text.
TextSize and Text properties are only available to views that show text.

- Image - Sets the image file (write-only). Only supported by ImageView.

- Visible - Gets or sets the view's visible property.

Methods:

- SetLeftAndRight (Left, Right) - Sets the view's left and right properties. This method changes the width of the view based on the two values.

- SetTopAndBottom (Top, Bottom) - Sets the view's top and bottom properties. This method changes the height of the view based on the two values.

Keywords:

- Min / Max - Same as the standard Min / Max keywords.
- AutoScale - Autoscales a view based on the device physical size.
Example:
B4X:
AutoScale(Button1)
- AutoScaleAll - Autoscales all layout views.
Example:
B4X:
AutoScaleAll
- AutoScaleRate - Sets the scaling rate, a value between 0 to 1. The default value is 0.3
Example:
B4X:
AutoScaleRate(0.2)

- ActivitySize - Returns the approximate activity size measured in inches.

- If ... Then condition blocks - Both single line and multiline statements are supported. The syntax is the same as the regular If blocks.

- Landscape (v3.20) - Returns True if the current orientation is landscape.
- Portrait (v3.20) - Returns True if the current orientation is portrait.

Notes and tips

- %x and %y values are relative to the view that loads the layout.
Usually it will be the activity. However it you use Panel.LoadLayout then it will be relative to this panel.
Note that ScrollView inner panel width is set to -1. This is a special value that causes the panel to fill its parent available size.
If you want to load a layout file (with a script) to the inner panel then you will need to first set the panel width: ScrollView.Panel.Width = ScrollView.Width.

- Use 'dip' units for all specified sizes (except of TextSize). By using 'dip' units the values will be scaled correctly on devices with higher or lower resolution.

- In most cases it is not recommended to create variants with scales other than 1.0. When you add such a variant you will be given an option to add a normalized variant instead with a scale of 1.0.

- Variables - You can use variables in the script. You do not need to declare the variables before using them (there is no Dim keyword in the script).

- Activity.RerunDesignerScript (LayoutFile As String, Width As Int, Height As Int) - In some cases it is desirable to run the script code again during the program. For example you may want to update the layout when the soft keyboard becomes visible. Activity.RerunDesignerScript method allows you to run the script again and specify the width and height that will represent 100%x and 100%y. In order for this method to work all the views referenced in the script must be declared in Sub Globals.
Note that this method should not be used to handle screen orientation changes. In that case the activity will be recreated and the script will run during the Activity.LoadLayout call.

It is recommended to continue to this tutorial: http://www.b4x.com/forum/basic4andr...ing-multiple-screens-tips-best-practices.html
 
Last edited:

aedwall

Active Member
Licensed User
Longtime User
Dimensions needed for Kindle

I made a variant of 600x1024 x1 for a Kindle, but the following does not seem to work properly:

btnChange.Right = 100%x
EditText1.Width = 100%x
EditText1.Top = btnDate.Bottom + 3dip
EditText1.Bottom = 100%y - 3dip

The EditText1 box should start just below the top buttons and extend to the bottom of the screen. My 320x480 and 480x800 variants seem to work correctly.
Thank you.
 

Attachments

  • ScreenShot_05-07-12 22;45;01001.png
    ScreenShot_05-07-12 22;45;01001.png
    22.8 KB · Views: 628

aedwall

Active Member
Licensed User
Longtime User
Thank you. This fixed it.

But now I get no word-wrap in my edit box - everything is all on one line. It didn't do this before I added code in the variants script. Adding "EditText1.Wrap = True" doesn't help.
 

aedwall

Active Member
Licensed User
Longtime User
It appears that including this statement:

EditText1.InputType = EditText1.INPUT_TYPE_NONE

turns off word-wrap, no matter what. This can't be right.
 

aedwall

Active Member
Licensed User
Longtime User
'NOTE: if I set the below InputType, then I lose word-wrap, no matter what.
'EditText1.InputType = EditText1.INPUT_TYPE_NONE 'do not allow software keypad to appear
EditText1.Wrap = True

The above works.

When I uncomment out the line that reads .InputType, then it fails.
The .Wrap does not solve the problem.

The fix is apparently to add the .SingleLine instruction.

EditText1.InputType = EditText1.INPUT_TYPE_NONE 'do not allow software keypad to appear
EditText1.SingleLine = False
EditText1.Wrap = True
 
Last edited:

Kimmowich

Member
Licensed User
Longtime User
Problem with panel.height and buttons inside

hey

First of all I just love the the designer. Thanks for that :sign0098:

I have just hit the wall on a minor problem and I dont know what im doing wrong here.

I have a small panel where 2 buttons are placed. I can for some reason not center the buttons according to the panel.height. Infact, I cant even make the buttons touch the bottom of the panel with:

button1.SetTopAndBottom(0, panel1.Height)

Did test it on my phone (samsung galaxy s2) and emulator.

I have included the design if anyone would care to have a look at it. Would be nice if a fresh pair of eyes sees something I dont :)

sincerly
 

Attachments

  • main.bal
    4.7 KB · Views: 439

Kimmowich

Member
Licensed User
Longtime User
Thanks Erel for your fast response.

Now im curious.

The internal padding on a view, is there some way to get that value to compensate when designing? or is that not important at all?

sincerly
 

Jim Brown

Active Member
Licensed User
Longtime User
Hi Erel,
I am not sure why but my views are not scaling via the scripts.
Everything looks good in the designers abstract window (in many diffferent resolution settings). The script results also look fine when connected to a phone and/or tablet. However, when the app is compiled and run no scaling takes place

What I have is two Layout Variants for Portrait and Landscape
320x480 scale 1
480x320 scale 1

I have written the designer scripts for each layout in the lower box only. Everything based on percentages. Example:

b4aScripting.png



Here is the result in a complied app (Galaxy Tab 7). No scaling happens. The layout is pretty much a 320x480 layout
b4ascript_tab.png


Do I need to put any code in the top part of the script box?
 

vasper

Member
Licensed User
Longtime User
One quick question. Will the system choose the apropriate script according to landscape or portrait mode automatically? Or do I have to create Landscape modes for every variant?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The system chooses the closest variant it finds. For larger tablets is might choose the portrait variant even if the tablet is in landscape orientation.

I recommend you to only create a landscape version for the standard phone variant.
At least when you start designing. In most cases the general script should do the work for the larger tablets.
 

Hubert Brandel

Active Member
Licensed User
Longtime User
Hi,

I want to make the buttons bigger on a higher resolution.
By now I just add these lines to MAIN Sub Process_Globals:

B4X:
Sub Process_Globals
   ...
   Dim nDisplayFaktor  As Float
   Dim nDisplayFontAdd As Int  
   Dim lv As LayoutValues
   lv = GetDeviceLayoutValues
   
   If lv.Width <= 480 Then
      nDisplayFaktor  = 1.00
      nDisplayFontAdd = 0
... 
   Else
      nDisplayFaktor = 1.30
      nDisplayFontAdd = 2
   End If
   dim nButSizeX, nButSizeY as int

in the script code of the Main window I insert this:

B4X:
'All variants script
nButSizeX      = 60%x  
nButSizeY      = 60dip * nDisplayFaktor

gives me an 'unassigned variable' error on nDisplayFaktor.
If I set it in the script it works, but when I want to call a function to give back the right value, the function name is shown as unknown variable ?

I want to have a central value for the zoom faktor. Is there a way to do it with the skript ?
 

Hubert Brandel

Active Member
Licensed User
Longtime User
Thanks for that clarification. I will use %x to decide how to zoom the controls ;-)

PS: I would prefere dip, but they are smale because of a 4" Smartphone layout, but now there are big tablets and they want to have bigger fonts and controls ;)

:sign0098:
 
Top