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:

icebold

Member
Licensed User
Longtime User
this is excellent Erel! I'm testing this new feature.. it looks great!
Thanks again
 

hackhack

Active Member
Licensed User
Longtime User
You should not used 'dip' units with this value as it is already measured in physical units.

I'm also confused by this sentence. "As it is already" means it sound that "dip" units are physical units - I thought they were virtual units?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I will answer with an example. The physical size of a button with a width of 100 depends on the device scale.

However the physical size of a button with a width of 100dip will be 100/160 inch on all devices. So you can say that dip units are actually physical units.

Font sizes are also measures in physical units (and not pixels). So you should not use dip units with font sizes.
 

icebold

Member
Licensed User
Longtime User
Question

Hi Erel,
why do you say that is not recommended to create variants with scales other than 1.0 ?

I tried to set up a new variant for Samsung SII that is 480x800, scale 1.5 ( scale 240 dpi ) and the program suggests me to use 320x533, scale 1 at 160dpi and in fact the suggested variant works fine on the emulator.

Could it be more compatible with any devices?

Thanks
 

Creaky

Member
Licensed User
Longtime User
I'm as happy as a clam with these new designer scripts Erel! :sign0060:

But I hope you don't mind me making a few minor suggestions?

Minor suggestion #1:
When the Designer Scripts editor is active the views in the emu and AD are locked, I totally get that. But it would be nice to be able to select them and that the id of the selected view is shown somewhere in de script editor. Especially in layouts with a lot of views, it is sometimes impossible to see the id of a view in the AD because of the small size of the view. Now you have to switch back between the Designer Scripts editor and the layout tab just to find out what the name of a particular view is. <edit>An even better and very efficient solution would be that you can double click the view in the locked AD and that the ID of the view would be inserted in the designer script at the cursor position. :) </edit>

Minor suggestion #2:
It would be nice if the 'Variant specific' script was run before the 'All variants' script. The 'All variants' script will usually base the positions and sizes of a general set of views on the size and position of some specific views that need to be resized or repositioned according to a particular screen size. See the screenshots below.

In this example I want to base the size and position of the spinner and buttons on the size and position of the bottom EditText. The EditText has a different height for each layout variant though, which results in the spinner and buttons being positioned in the wrong way.

Wrong positioning:
Knipsel1.PNG


Right positioning:
Knipsel2.PNG


The only way I can achieve the right positioning is by moving my 'All variants' script to the bottom of my 'Variant specific' script.

If the 'Variant specific' script would run before the 'All variants' script, moving the 'All variants' script to the 'Variant specific' script would not be neccessary.

Apart from these suggestions I am very happy with the new designer scripts! :)
 
Last edited:

Paulsche

Well-Known Member
Licensed User
Longtime User
Spinner Textsize to smal

i design my Layout for Tablet with 800x1280 scale 1 160dpi ,

has the dimensions and size I make twice as large,
What goes well, I can only spinner in the script editor does not specify text size
the text is too small. how can I fix it ?

I have solved the problem in the code.
the text size of a button spinner just the same as defined
The button is defined in the script

SPN00Startseite_Objektfilter.TextSize = BTN00Startseite_Objektverwaltung.TextSize
 

Attachments

  • Script.png
    Script.png
    84.3 KB · Views: 882
  • screenshot.png
    screenshot.png
    37.8 KB · Views: 838
Last edited:

cymorg

Member
Licensed User
Longtime User
The designer scripts are top notch. Nevertheless I can't help myself reporting one (obvious?) missing feature.

Scroll bars on the Abstract Designer would mean that panels larger than the development machine's screen would be editable without zooming (which only works up to a certain size anyway).

Maybe add this to the wish list & keep up the good work. It is really appreciated.
 

pilbazan

Member
Licensed User
Longtime User
A new simple suggestion for the Designer

Hi Erel,
I have a simple suggestion for the next update:
It is possible to show a miniature of the 'image Files' added in the Designer? It will be faster that go to the folder 'Files' to see them when we want to delete one of them.

Thanks a lot and very good job. B4A is incredible!
 

JoanRPM

Active Member
Licensed User
Longtime User
Problem with the Designer Scrips

I just want to make a keyboard in a panel.
I try to make that all the buttons are relatives to the panel.
The buttons should be referenced to the panel, but it fails.
I made a simple example so the panel is in the center of activity and the button is in the center of the panel. But is not working.
I have in the designer scripts:

B4X:
'All variants script

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

Button1.HorizontalCenter = Panel1.HorizontalCenter
Button1.VerticalCenter = Panel1.VerticalCenter

Am I doing something wrong?
Here is the sample.

thanks
 

Attachments

  • Prova_script1.zip
    8.9 KB · Views: 573

Erel

B4X founder
Staff member
Licensed User
Longtime User
There are two issues here.
First, as Button1 is a child of Panel1 its coordinates are related to Panel1.
You should change your code to:
B4X:
Panel1.HorizontalCenter = 50%x
Panel1.VerticalCenter = 50%y

Button1.HorizontalCenter = Panel1.HorizontalCenter - Panel1.Left
Button1.VerticalCenter = Panel1.VerticalCenter - Panel1.Top

This will work correctly in the compiled app. However there is a bug in the designer with the value returned from HorizontalCenter. So in the designer the button will be slightly left from the center.
This bug will be fixed in the next update.
 

JoanRPM

Active Member
Licensed User
Longtime User
Erel.
Yes, it is true, the compiled version works perfectly. In the designer, will have to wait the next version.
I thought that because the button was related with the panel, it is not necessary to subtract the starting position.
Thanks for your quick response. You do not rest ever?
Regards.
 

RomanR

New Member
Licensed User
Longtime User
Awesome tool - minor suggsstion

Hi Erel,

you have created an awesome tool for programming android-devices and an absolute cool feature for designing layouts.
However I have another suggestion for the designer script:
make an easy way to create different layouts for horizontal and vertical layouts in the "All variants script". It is often better to split the layout than to stretch it.

Thanks again :icon_clap:
 

RiverRaid

Active Member
Licensed User
Longtime User
@RomanR + 1

I have the same problem.. I use different variants for landscape and portrait.
But f.i on my Galaxy S2, the layoutvariant script doesn't work (because dpi = 1.5).

Is there a possibility to just do the scripts for landscape and portrait (regardles of dpi, width & height)?
 

Attachments

  • designer.jpg
    designer.jpg
    80.3 KB · Views: 757

Ebass

New Member
Licensed User
Longtime User
Im staring to use Basic4Android, but thinks this its a great feature!

Thanks Erel!
 
Top