Beginners Guide
Beginners Guide
Edition 2.9
Table of contents
Undo Redo
................................................................................................. 61
Collapse a subroutine ................................................................................................. 61
Collapse a Region ...................................................................................................... 62
Collapse the whole code............................................................................................. 63
......................................................... 64
4.2.7 Bookmarks
..................................................................................... 64
4.2.8 Indentation
................................................................................................... 65
4.2.9 Autocomplete
..................................................................................................... 67
4.2.10 Built in documentation ........................................................................................... 69
4.2.11 Jump to a subroutine .............................................................................................. 70
4.2.12 Highlighting occurrences of words......................................................................... 71
4.2.13 Debugging ............................................................................................................. 72
4.2.13.1
Debug (legacy) mode ..................................................................................... 72
4.2.13.2
Debug (rapid) mode........................................................................................ 74
4.2.13.3
Release and Release (obfuscated) modes ........................................................ 80
4.2.14 Breakpoints............................................................................................................ 81
4.2.15 Color Picker ........................................................................................................... 84
4.3
Tabs............................................................................................................................... 85
4.3.1 Module and subroutine lists
................................................................... 85
4.3.1.1 Find Sub Tool (Ctrl + E) .................................................................................... 86
4.3.1.2 Find All References (F7) .................................................................................... 87
4.3.2 Files
........................................................................................................... 88
4.3.3 Logs
.......................................................................................................... 89
Table of contents
4.3.3.1
4.3.4 Libs
............................................................................................................ 97
Screen sizes and resolutions................................................................................................... 98
5.1
Special functions like 50%x, 50dip ............................................................................ 103
5.1.1 PerXToCurrent, PerYToCurrent - 50%x .................................................................. 103
5.1.2 DipToCurrent - 50dip............................................................................................... 103
5.2
Working with different screen sizes / number of layouts .............................................. 104
5.3
Screen orientations....................................................................................................... 110
5.4
Supporting multiple screens - tips and best practices .................................................... 111
5.4.1 Advices.................................................................................................................... 111
5.4.1.1 'dip' units.......................................................................................................... 111
5.4.1.2 Use only a few layout variants.......................................................................... 111
5.4.1.3 Understand the meaning of scale (dots per inch)............................................... 111
5.4.1.4 "Normalized" variants ...................................................................................... 111
5.4.1.5 Scaling strategy................................................................................................ 112
5.4.1.6 How to change the views size and text size? AutoScale .................................. 112
6
The Emulator....................................................................................................................... 113
6.1
Launch an Emulator..................................................................................................... 113
6.2
Create a new Emulator................................................................................................. 115
6.3
Emulator problems....................................................................................................... 118
6.3.1 Process timeout........................................................................................................ 119
6.4
Exchanging files with the PC ....................................................................................... 120
7
Connecting a real device USB / B4A Bridge.................................................................... 123
7.1
USB............................................................................................................................. 123
7.2
B4A Bridge ................................................................................................................. 124
7.2.1 First you need to install B4A-Bridge on your device. ............................................... 124
7.2.2 Run B4A-Bridge on your device. ............................................................................. 125
7.2.3 Connect the IDE to the device.................................................................................. 125
7.2.3.1 Wireless connections........................................................................................ 125
7.2.3.2 Bluetooth connections ...................................................................................... 126
7.2.3.3 Bluetooth tips ................................................................................................... 128
8
The Designer ....................................................................................................................... 129
8.1
The menu..................................................................................................................... 130
8.1.1 File menu................................................................................................................. 130
8.1.2 Edit menu ................................................................................................................ 130
8.1.3 AddView menu........................................................................................................ 131
8.1.4 The Tools menu ....................................................................................................... 132
8.2
Tools ........................................................................................................................... 133
8.2.1 Generate Members ................................................................................................... 133
8.2.2 BringTo Front .......................................................................................................... 134
8.2.3 Send To Back........................................................................................................... 134
8.2.4 Duplicate Selected View .......................................................................................... 134
8.2.5 Remove Selected View ............................................................................................ 135
8.2.6 Change grid ............................................................................................................. 135
8.2.7 Connect device or emulator...................................................................................... 136
8.3
General settings ........................................................................................................... 137
8.4
Image files ................................................................................................................... 139
8.5
Properties list ............................................................................................................... 140
8.6
Layout variants ............................................................................................................ 142
8.7
The Abstract Designer ................................................................................................. 147
8.7.1 The menu................................................................................................................. 148
8.7.2 Context menus ......................................................................................................... 149
8.7.3 Select views ............................................................................................................. 150
5
Table of contents
Table of contents
Table of contents
Table of contents
1 Getting started
Getting started
Basic4android is a simple yet powerful development environment that targets Android devices.
Basic4android language is similar to Visual Basic language with additional support for objects.
Basic4android compiled applications are native Android applications; there are no extra runtimes or
dependencies.
Unlike other IDEs, Basic4android is 100% focused on Android development.
Basic4android includes a powerful GUI designer with built-in support for multiple screens and
orientations. No XML writing is required.
You can develop and debug with the Android emulator or with a real device
(USB-connected or over the local network).
Basic4android has a rich set of libraries that make it easy to develop advanced applications.
This includes: SQL databases, GPS, Serial ports (Bluetooth), Camera, XML parsing, Web services
(HTTP), Services (background tasks), JSON, Animations, Network (TCP and UDP), Text To Speech
(TTS), Voice Recognition, WebView, AdMob (ads), Charts, OpenGL, Graphics and more.
1 Getting started
1.1
Trial version
The trial version has a new compilation mode called Remote Compilation Mode to avoid the
installation of the two components Java JDK and Android SDK.
This remote compilation mode is only available in the trial version.
Requirements:
You need to install the program B4A-Bridge on your device.
- You can download it here: http://www.basic4ppc.com/android/files/b4a_bridge.apk.
- B4A-Bridge is also available in Android market. Search for: B4A Bridge.
Look at chapter 7 B4A Bridge in this guide.
1 Getting started
1.2
10
1 Getting started
11
1 Getting started
12
1.3
13
Please follow the installation (and configuration) instructions if you have not done it yet:
http://www.basic4ppc.com/forum/basic...droid-sdk.html.
In this chapter we will create a new AVD (Android Virtual Device) which is an emulator;
software on the PC that 'emulates' a device. It's a virtual device and not a real device.
Then we will create a simple program that displays a simple message box and writes a message to
the log.
You can also connect a real device to the IDE and run the program on your actual device instead of
running it on the virtual device:
Connecting your device with ADB
Connecting your device with B4A-Bridge Chapter 7
Create new AVD
- Run Basic4android.
- Choose Tools Menu - Run AVD Manager.
Wait a few seconds.
- The AVD Manager should appear:
- Click on
and refer to the following image to fill in the fields with similar values.
14
Enter a name.
Select a device, in the example the
'standard' screen 320 x 480 pixels.
Select the Android target version.
- Click on
15
- Click on
- You will see several windows popping up and disappearing. This is normal.
16
Wait. The first time it can take several minutes before the emulator is ready.
17
Click on
18
You may see screens like below depending on the Android target Version.
2 My first program
19
Let us write our first program. The suggested program is a math trainer for kids.
The project is available in the SourceCode folder :
SourceCode\MyFirstProgram\ MyFirstProgram.b4a
The look of the screen is different depending on the Android version, even with Emulators.
Emulator Android version 4.2
2 My first program
20
2 My first program
21
The default name is B4A Example, but we will change it to MyFirstProgram for naming
consistency.
Change this line:
#ApplicationLabel: B4A Example
to
#ApplicationLabel: MyFirstProgram
The other lines are explained in Chapter 4.2.1 Code header Project Attributes / Activity Attributes.
2 My first program
22
Click on
2 My first program
23
Click on
2 My first program
24
2 My first program
25
The label appears in the Emulator, and its default properties are listed in the Designer.
Resize and move the Label with the red
squares like this.
2 My first program
26
We have now:
Main :
main module.
Name :
name of the view.
Type :
type of the view. In this case, Label, which is not editable.
Event Name : generic name of the routines that handle the events of the Label.
Parent :
parent view the Label belongs to.
2 My first program
27
We need a second Label similar to the first one. Instead of adding a new one, we copy the first one
with the same properties. Only the Name and Left properties will change.
The
new
label
covers
the
previo
us one.
2 My first program
28
Let us position the new Label and change its name to lblNumber2.
Let us now add a 3rd Label for the math sign. We copy once again lblNumber1.
Click on lblNumber1 in the Emulator, and in the Designer click in the 'Tools' menu on 'Duplicate
Selected View'.
Position it between the first two Labels and change its name to lblMathSign and its
Text property to '+'.
2 My first program
29
Position it below the three Labels and change its name to edtResult. 'edt' means EditText and
'Result' for its purpose.
Horizontal Alignment
Text Size
to 30
Input Type
Hint Text
to CENTER_HORIZONTAL
to NUMBERS
to Enter result
Setting Input Type to NUMBERS lets the user enter only numbers.
Hint Text represents the text shown in the EditText view if no text is entered.
2 My first program
30
Now, let's add the Button which, when pressed, will either check the result the user supplied as an
answer, or will generate a new math problem, depending on the user's input.
Position it below the EditText view. Resize it and change following properties:
Name
to btnAction
Text
Text Size to 24
2 My first program
31
Let us add the last Label for the comments. Position it below the Button and resize it.
The result will look like below depending on the Android version.
2 My first program
32
Click on
Click on
To write the routines for the project, we need to reference the Views in the code.
This can be done with the Generate Members tool in the Designer.
2 My first program
33
The Generate Members tool automatically generates references and subroutine frames.
Click on
btnAction As Button
edtResult As EditText
lblComments As Label
lblMathSign As Label
lblNumber1 As Label
lblNumber2 As Label
Sub btnAction_Click
End Sub
Click on
2 My first program
34
- Enter a dot
- The autocomplete function shows all the possible properties of the view.
- Enter 'L' , and the autocomplete function shows the properties beginning with 'L'
- Press the down arrow key, and LoadLayout will be highlighted with the online help for the given
property or method.
2 My first program
35
- Press '(' to display the online help showing the needed properties for the method.
- Enter "Main"
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Main")
End Sub
We want to generate a new problem as soon as the program starts. Therefore, we add a call to the
New subroutine.
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Main")
New
End Sub
Generating a new problem means generating two new random values between 1 and 9 (inclusive)
for Number1 and Number2, then showing the values using the lblNumber1 and lblNumber2 Text
properties.
To do this we enter following code:
In Sub Globals we add two variables for the two numbers.
Dim Number1, Number2 As Int
End Sub
The following line of code generates a random number from '1' (inclusive) to '10' (exclusive) :
Rnd(1, 10)
2 My first program
36
result" & CRLF & "Enter a new result" & CRLF & "and click OK"
With If edtResult.Text = Number1 + Number2 Then we check if the entered result is correct.
If yes, we display in the lblComments label the text below:
'G O O D result'
'Click on NEW'
and we change the Button text to "N E W ".
If no, we display in the lblComments label the text below:
W R O N G result
Enter a new result
and click OK
2 My first program
37
When you see 'Completed successfully.' as in above message box, the compiling and transfer
is finished.
Looking at the emulator, you should see something similar to the image below, with different
numbers.
2 My first program
38
3 Second program
39
3 Second program
40
Then we must change the ApplicationLabel on the very top of the code.
#Region Project Attributes
#ApplicationLabel: SecondProgram
Click on
Duplicate it
3 Second program
41
to lblResult
Text
Text Color
to Black
Corner Radius
Color
Alpha
to 5
to White
to 255
3 Second program
42
Change
Corner radius to 0
Color
to ControlDarkDark
3 Second program
43
Now we rearrange the views to get some more space for the
keyboard.
Set the Height property of the 4 Labels to 50 instead of 60.
Set the Top property of label lblResult to 60.
Set the Top property of label lblComments to 120.
Set the Top property of panel pnlKeyboard to 210.
Set the Height property of panel pnlKeyboard to 180.
3 Second program
44
Click on
to add a new button.
to btn0
to btnEvent
Left
Top
Width
Height
to 0
to 120
to 55
to 55
Tag
Text
to 0
to 0
Size
TextColor
to 24
to Black
3 Second program
45
Click on GradientDrawable
TOP_BOTTOM
Pressed Drawable
to GradientDrawable
Orientation
to
First Color
Second Color
TOP_BOTTOM
3 Second program
46
to btn1
Tag
Text
to 1
to 1
3 Second program
47
<
btnAction
OK
3 Second program
48
Click on Find(F3)
3 Second program
49
Click on
Click on
and
Now we write the routine that handles the Click events of the Buttons.
The Event Name for all buttons, except btnAction, is "btnEvent".
The routine name for the associated click event will be btnEvent_Click.
Enter the following code:
Sub btnEvent_Click
End Sub
We need to know what button raised the event. For this, we use the Sender object which is a special
object that holds the object reference of the view that generated the event in the event routine.
Sub btnEvent_Click
Dim btnSender As Button
btnSender = Sender
Select btnSender.Tag
Case "BS"
Case Else
End Select
End Sub
Select btnSender.Tag
Case "BS"
Case Else
3 Second program
50
The "&" character means concatenation, so we just append to the already existing text the value of
the Text property of the button that raised the event.
Now we add the code for the BackSpace button.
Select btnSender.Tag
Case "BS"
If lblResult.Text.Length >0 Then
lblResult.Text = lblResult.Text.SubString2(0, lblResult.Text.Length - 1)
End If
Case Else
lblResult.Text = lblResult.Text & btnSender.Text
End Select
End Sub
When clicking on the BS button we must remove the last character from the existing text in
lblResult.
However, this is only valid if the length of the text is bigger than 0. This is checked with:
If lblResult.Text.Length >0 Then
3 Second program
51
We can try to improve the user interface of the program by adding some colors to the lblComments
Label.
Let us set:
- Yellow
for a new problem
- Light Green for a GOOD answer
- Light Red for a WRONG answer.
Let us first modify the New routine, where we add the line lblResult.Text = ""...
Sub New
Number1 = Rnd(1, 10)
' Generates a random number between 1 and 9
Number2 = Rnd(1, 10)
' Generates a random number between 1 and 9
lblNumber1.Text = Number1 ' Displays Number1 in label lblNumber1
lblNumber2.Text = Number2 ' Displays Number2 in label lblNumber2
lblComments.Text = "Enter the result" & CRLF & "and click on OK"
lblComments.Color = Colors.RGB(255,235,128) ' yellow color
lblResult.Text = ""
' Sets lblResult.Text to empty
End Sub
"Click on NEW"
' light green color
& "Enter a new result" & CRLF & "and click OK"
' light red color
3 Second program
52
Another improvement would be to hide the '0' button to avoid entering a leading '0'.
For this, we hide the button in the New subroutine in line btn0.Visible = False.
Sub New
Number1 = Rnd(1, 10)
' Generates a random number between 1 and 9
Number2 = Rnd(1, 10)
' Generates a random number between 1 and 9
lblNumber1.Text = Number1 ' Displays Number1 in label lblNumber1
lblNumber2.Text = Number2 ' Displays Number2 in label lblNumber2
lblComments.Text = "Enter the result" & CRLF & "and click on OK"
lblComments.Color = Colors.RGB(255,235,128) ' yellow color
lblResult.Text = ""
' Sets lblResult.Text to empty
btn0.Visible = False
End Sub
In addition, in the btnEvent_Click subroutine, we hide the button if the length of the text in
lblResult is equal to zero and show it if the length is greater than zero, lines 98 to 102.
Sub btnEvent_Click
Dim btnSender As Button
btnSender = Sender
Select btnSender.Tag
Case "BS"
If lblResult.Text.Length >0 Then
lblResult.Text = lblResult.Text.SubString2(0,lblResult.Text.Length - 1)
End If
Case Else
lblResult.Text = lblResult.Text & Send.Tag
End Select
If lblResult.Text.Length = 0 Then
btn0.Visible = False
Else
btn0.Visible = True
End If
End Sub
As we are accessing btn0 in the code we need to declare it in the Globals routine.
Modify line 25 like below:
Dim btnAction, btn0 As Button
4 The IDE
53
The IDE
Module list
List containing all module names.
Clicking on one of the names jumps directly to the selected module.
Subroutine list
List of the subroutines in the current module.
Clicking on one of the names jumps directly to the selected routine.
Tabs
4 The IDE
4.1
54
4.1.1 Toolbar
Generates a new empty project.
Loads a project.
Saves the current project.
Copies the selected text to the clipboard.
Cuts the selected text and copies it to the clipboard.
Pastes the text in the clipboard at the cursor position.
Undoes the last operation.
Redoes the previous operation.
Activates the Find and Replace function.
Sets the selected lines as comments.
Uncomments the selected lines.
Navigate backwards
Navigate forwards
Adds a bookmark.
Removes a bookmark.
Go back to the previous bookmark.
Go forward to the next bookmark.
Autocomplete function Ctrl + space.
Decrease the indentation of the selected lines.
Increase the indentation of the selected lines.
Runs the compiler.
Compiler options list and Debugging
Routine list
4 The IDE
55
New
Generates a new empty
project.
Open Source Loads a project.
Save
Saves the current project.
Export As Zip Exports the whole project
in a zip file.
Page Setup
Setup pages for printing
Print Preview Shows a print preview.
Print
Prints the code.
Exit
Leaves the IDE.
List of last loaded programs.
Cut
clipboard.
Cut Line
Copy
Paste
position.
Undo
Redo
Find
Block Comment
Sets the selected lines as comments.
Block Uncomment Uncomments the selected lines.
Remove All Bookmarks
Remove All Breakpoints
Outlining
Bookmarks.
Breakpoints.
4 The IDE
56
IDE Options
see below
Take Screenshot
4 The IDE
57
4 The IDE
58
Clicking on
shows this window.
Click on
to take the
screenshot picture from the device or the
emulator.
You can resize the image.
4.2
59
Code area
The code of the selected module is displayed in this area and can be edited.
The examples below are based on the code of the SecondProgram.
When you load a project saved with a version of B4A older than 2.5 then the header will look like
this:
#Region Module Attributes
#FullScreen: False
#IncludeTitle: True
#ApplicationLabel: MyFirstProgram
#VersionCode: 1
#VersionName:
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region
When you add a new Activity you'll find the Activity Attributes region on top.
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
When you add a new Service you'll find the Service Attributes header.
#Region Service Attributes
#StartAtBoot: False
#End Region
60
When you want to add a new Attribute you can just write # and the inline help shows all
possibilities.
61
to undo and on
to redo.
Hovering with the mouse over the collapsed routine name shows its content.
62
Then you can add the subroutines between the two limits:
Then clicking on
shows the beginning of the code, not all the routines in the region.
63
64
Original code
4.2.7 Bookmarks
You can set 'bookmarks' anywhere in the code and jump forward and backwards between these
bookmarks.
To set a bookmark, position the cursor on the
desired line, 12 in this example.
Click on
Click on
In the
65
4.2.8 Indentation
A good practice is to use the indentation of code parts.
For example for subroutines, loops, structures etc.
Example with an
indentation of 4
Personally,
I prefer a value of 2.
66
Original code
67
4.2.9 Autocomplete
A very useful tool is the autocomplete function.
Example:
Let us write lblN
Press on Ctrl + Space or click on
68
Press Tab.
69
If you want to add a code example you can use <code> tags:
Code:
'Parses a raw mail message and returns a Message object
'Mail - The mail raw text
'AttachmentsDir - Attachments will be saved in this folder
'
'Example: <code>
'Dim m As Message
'm = MailParser.ParseMail("Content-Type: text/plain; charset=" & QUOTE & "utf8" & QUOTE, File.DirRootExternal)
'Log(m)</code>
70
71
72
4.2.13 Debugging
To allow debugging you must activate one of the two debugging modes Debug (legacy) or
Debug (rapid) on top of the IDE.
4.2.13.1
Let's first select Debug(legacy) : When this option is selected then the
compiled code will contain debugging code.
The debugging code allows the IDE to connect to the program and inspect
it while it runs.
When the program starts, it will wait for up to 10 seconds for the IDE to
connect. Usually the IDE will connect immediately. However if you run your program manually
from the phone you will see it waiting.
The name of the compiled APK file will end with _DEBUG.apk. You should not distribute this apk
file as it contains the debugging code which adds a significant overhead.
To distribute files you must select the Release or the Release (obfuscated) option.
When we run the program with the Debug (legacy) option, the IDE will open the debugger module
at the bottom of the screen:
73
74
Very quick compilation and installation. Usually in less than one or two seconds.
In most cases (after the first installation) there is no need to reinstall the APK. This means
that the deployment is much quicker. With B4A-Bridge there is no need to approve the
installation.
Hot code swapping (edit and continue). You can modify the code while the app runs, hit
Save and the code will be updated.
Watch Expressions feature.
Powerful variables browser:
75
Limitations:
The runtime execution in this mode is almost as rapid like non debugging. The rapid
debugger is not suitable for debugging "real-time" games or CPU intensive tasks. This is
why the legacy debugger is kept.
Hot code swapping is very powerful. You can even add subs or modify existing subs.
However you cannot add or remove global variables.
Unlike the legacy debugger, the app cannot run when the IDE is not connected. It will wait
for 10 seconds for the IDE to connect and then exit.
76
Small example, the code DebugRapid.b4a is in the DebugRapid folder in the source code folder :
77
to btnDraw.Left = 10dip
and click on
If you set a breakpoint in the code and run it, you will find a window in the lower part of the screen
showing all objects with their properties and all variables with their current values.
or
78
You can click on a variable in the code to show its value in the variable browser.
Other example:
Clicking on the variable col .
Clicking on an object in the code, btnDraw in the example, shows all properties of this object in the
variable browser.
79
This adds a new watch expression in the list with its value.
Clicking on
80
81
4.2.14 Breakpoints
Clicking on a line in the left margin adds a breakpoint. When the program is running it stops at the
first breakpoint. Breakpoints, in Globals, Process_Globals and Activity_Pause are ignored.
The IDE behaves differently depending on the debug mode. The examples below are for the
legacy debug mode. For the rapid debug mode look in the Debug (rapid) mode chapter.
Run the program, the program stops at the breakpoint and the IDE looks like below. The breakpoint
line is highlighted in yellow.
Debugger is connected.
Double click to detach the Debugger.
Name of the routine where the program stopped.
New routine at line 52.
Caller of New routine : Activity_Create routine in line 24.
Clicking on these links jumps the cursor to the given line.
82
Global variables.
List of the global
objects and variables
used by the program
with their values and
properties.
Examples:
btnAction: Type = Button Left = 190 Top = 0 Width = 115 Height = 55 Tag = empty Text = OK
Number1 = 6
Local variables.
None in this example.
Hovering with the mouse over a view shows its properties like in the list.
83
Click on F8.
The program executes the next code line.
Click on F8.
The program executes the next code line.
84
Select a color, and its value will be copied to the Clipboard. You may then paste the value into your
code.
4.3
85
Tabs
There are 4 tabs at the bottom right corner of the IDE that
display the following information.
see below
see below
86
87
Click on
object.
you get the list below with all code lines containing the selected
Clicking on a line in the list shows that line in the middle of the IDE code area.
88
4.3.2 Files
This window lists all the files that have been added to the project.
These files are saved in the Files subfolder under your main project folder.
These can be any kind of files: layouts, images, texts, etc.
Click on
to add files to the list.
The files in that subfolder can be accessed from your
program by using the reference File.DirAssets.
Make sure to have a copy of the files you remove, because they are removed from the Files
folder, but not transferred to the Recycle Bin, which means that they are definitely lost if you
don't make a copy.
89
4.3.3 Logs
Display of Log comments generated by the program when it is running.
We add the two lines 51 and 53 in the program 'SecondProgram' in the 'New' routine.
The number of the lines may be different from yours.
When Filter is checked you will only see messages related to your program. When it
is unchecked you will see all the messages running in the system. If you are encountering an error
and do not see any relevant message in the log, it is worth unchecking the filter option and looking
for an error message
Click
If the debugger is still running, do one of the following to edit the code :
- Select Debug > Stop from the IDE menu.
- Press F11 shortcut key.
-
Or click on
90
in the
menu, or
The compile-time warnings appear above the logs and in the code itself when hovering with the
cursor above the code line.
The code lines which caused the warning are underlined like
this .
Clicking on the warning in the list will take you to the relevant code.
Ignoring warnings
You, as the developer, can choose to ignore any warning. Adding an "ignore" comment will disable
all the warnings for that specific line:
Sub UnusedSub(a As Int) 'ignore
You can also disable warnings from a specific type in the module by adding the #IgnoreWarning
attribute in the Project Attributes or Module Attributes regions.
For example, to disable warnings #10 and #12:
#Region Project Attributes
#ApplicationLabel: Warnings
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#IgnoreWarnings: 10, 12
#End Region
91
Runtime warnings
Some of the warnings are only checked at runtime. These warnings will appear in the regular logs.
Runtime warnings are only checked in Debug mode.
List of warnings
1: Unreachable code detected.
2: Not all code paths return a value.
3: Return type (in Sub signature) should be set explicitly.
4: Return value is missing. Default value will be used instead.
5: Variable declaration type is missing. String type will be used.
6: The following value misses screen units ('dip' or %x / %y): {1}.
7: Object converted to String. This is probably a programming mistake.
8: Undeclared variable '{1}'.
9: Unused variable '{1}'.
10: Variable '{1}' is never assigned any value.
11: Variable '{1}' was not initialized.
12: Sub '{1}' is not used.
13: Variable '{1}' should be declared in Sub Process_Globals.
14: File '{1}' in Files folder was not added to the Files tab.\nYou should either delete it or add it to
the project.\nYou can choose Tools - Clean unused files.
15: File '{1}' is not used.
16: Layout file '{1}' is not used. Are you missing a call to Activity.LoadLayout?
17: File '{1}' is missing from the Files tab.
18: TextSize value should not be scaled as it is scaled internally.
19: Empty Catch block. You should at least add Log(LastException.Message).
20: View '{1}' was added with the designer. You should not initialize it.
21: Cannot access view's dimension before it is added to its parent.
22: Types do not match.
23: Modal dialogs are not allowed in Sub Activity_Pause. It will be ignored.
24: Accessing fields from other modules in Sub Process_Globals can be dangerous as the
initialization order is not deterministic.
'Runtime warnings
1001: Panel.LoadLayout should only be called after the panel was added to its parent.
1002: The same object was added to the list. You should call Dim again to create a new object.
1003: Object was already initialized.
1004: FullScreen or IncludeTitle properties in layout file do not match the activity attributes
settings.
92
Correct code
Sub Activity_KeyPress(KeyCode As Int) As Boolean
Dim Answ As Int
Dim Txt As String
If KeyCode = KeyCodes.KEYCODE_BACK Then' Checks if the KeyCode is BackKey
Txt = "Do you really want to quit the program ?"
Answ = Msgbox2(Txt,"A T T E N T I O N","Yes","","No",Null) ' MessageBox
If Answ = DialogResponse.POSITIVE Then
' If return value is Yes then
Return False
' Return = False the Event will not be consumed
Else
' we leave the program
Return True
' Return = True
the Event will be consumed to avoid
End If
' leaving the program
Else
Return True
' Return = True
the Event will be consumed to avoid
End If
' leaving the program
End Sub
Correct code
Sub Calc(Val1 As Double, Val2 As Double, Operation As String) As Double
93
Correct code
Sub CalcSum(Val1 As Double, Val2 As Double) As Double
Dim Sum As Double
Sum = Val1 + Val2
Return Sum
End Sub
Correct code
Sub Calc(Val1 As Double, Val2 As Double, Operation As String) As Double
Correct code
Activity.AddView(lblTest, 10dip, 10dip, 150dip, 50dip)
In the example above you will get four warnings, one for each value.
For view dimensions you should use dip, %x or %y values.
See chapter 5.1 Special functions like 50%x, 50dip
7: Object converted to String. This is probably a programming mistake.
8: Undeclared variable '{1}'.
Wrong code
Sub SetHeight
h = 10dip
End Sub
Correct code
Sub SetHeight
Dim h As Int
h = 10dip
End Sub
The variable h was not declared. You see it also with the red color.
94
This warning shows that the variable h is declared but not assigned any value.
Correct code see above.
11: Variable '{1}' was not initialized.
Wrong code
Dim lst As List
lst.Add("Test1")
Correct code
Dim lst As List
lst.Initialize
lst.Add("Test1")
Variables (objects) like List or Map must be initialized before they can be used.
Views added by code must also be initialized before they can be added to a parent view.
12: Sub '{1}' is not used.
This warning is displayed if a Sub routine is never used.
13: Variable '{1}' should be declared in Sub Process_Globals.
Wrong code :
Sub Globals
Dim Timer1 As Timer
Dim GPS1 As GPS
Correct code :
Sub Process_Globals
Dim Timer1 As Timer
Dim GPS1 As GPS
Certain objects like Timers and GPS should be declared in Process_Globals, not in Globals.
95
14: File '{1}' in Files folder was not added to the Files tab.
You are using a file which is in the Files folder, but was not added to the Files tab.
You should:
- Make a backup copy.
- Delete it from the Files subfolder.
- Add it to the project in the Files tab.
- Use Clean Files Folder (unused files) in the Tools menu.
Correct code
lblTest.TextSize = 16
TextSize values are pixel and density independent. Their unit is the typographic point, a
typographic unit, and must be given absolute values and not dip values.
96
Correct code
Try
imvImage.Bitmap = LoadBitmap(File.DirRootExternal, "image.jpg")
Catch
Log(LastException.Message)
End Try
97
4.3.4 Libs
The Libs tab contains a list of the available libraries that can be used in the project.
Check the libraries you need for your project.
Make sure that you have the latest version of the libraries.
Enter AH in the fiesl and you gat all libraries beginning with AH.
The list of all additional libraries can be found here : Additional Libraries.
The documentation for libraries can be found here :
Basic4android - Android programming with Gui designer
98
There exist many different screen sizes with different resolutions and pixel densities.
We must explain the difference between the following parameters.
- Physical screen size
Ex: 3.6 '' diagonal
- Resolution in pixels
Ex: 320 / 480
- Density pixels per inch
Ex: 160
The standard screen is 320 / 480 pixels, density 160 pixels/inch.
There exist other screens with almost the same physical size but with a higher resolution (for
example 480 / 640 pixels with a density of 240 pixels/inch).
Tablets have bigger physical sizes but can have a density similar to the standard screen.
Example: 7.2 '' screen diagonal, 640 / 960 pixels and a density of 160 pixels/inch.
A non-exhaustive list of screens:
Diagonal
3.5
3.5
3.9
3.5
5
7
7
10
10
10
Resolution
320 / 480
480 / 720
480 / 800
240 / 320
1080 / 1920
640 / 960
800 / 1280
768 / 1024
800 / 1280
1200 / 1920
Density
160
240
240
120
480
160
160
160
160
240
Scale
1
1.5
1.5
0.75
3
1
1
1
1
1.5
W / H Ratio
3/2
3/2
5/3
4/3
4/3
3/2
16 / 9
4/3
16 / 10
16 / 10
In cases 1) 2) and 3) the physical sizes of the screens are the same but the density of the pixels is
different.
In cases 1) and 4) the densities are the same, but the physical dimensions of the screen in case 4)
are double the dimensions of screen 1), yielding 4 times the area, and 4 times total number of
pixels.
Let us look at the physical size of a button with 80 / 80 dip.
dips
pixels
inch
1)
80
80
0.5
2)
80
120
0.5
2)
-80
0.375
dimension given in pixels not in dips
3)
80
160
0.5
3)
-80
0.25
dimension given in pixels not in dips
4)
80
80
0.5
dip = density independent pixel
It is possible to generate special Emulators with special sizes, resolutions and densities.
99
A same layout can fit into different screen resolutions, but with some restrictions.
We will use the TestLayouts program to test the same layout with different screen resolutions.
The source code is in the <Guide>\SourceCode\TestLayouts directory.
The different resolutions are:
Screen
resolution
240 / 320
320 / 480
480 / 800
Density
H / W ratio
120
160
240
4/3
3/2
5/3
Equivalent
height pixels
360
480
720
Pixel diff.
- 40
0
+ 80
100
Note that lines 38 and 39 are commented out (lines 41 and 42 too for landscape)!
Tests with the three Emulators with different resolutions and different densities.
The image sizes are reduced by a factor of 0.5 for easier comparison.
What we see:
- with the standard resolution, the image in the emulator is equal to the original layout.
- with the 240/320 resolution we see that there are the 'expected' 40 pixels missing.
- with the 480/800 resolution, we see that there are the 'expected' 80 extra pixel.
The numbers of items in the ListView are the same for all three resolutions.
101
Second test with lines 38 and 39 activated (and 41 and 42 for landscape).
If Activity.Height>Activity.Width Then
pnlToolBox.Top=Activity.Height-pnlToolBox.Height
ListView1.Height=pnlToolBox.Top-ListView1.Top-10dip
Else
pnlToolBox.Left=Activity.Width-pnlToolBox.Width
ListView1.Width=pnlToolBox.Left-ListView1.Left-10dip
End If
In line 38 we calculate the top of the pnlToolBox panel according to the screen height.
In line 39 we calculate the ListView height according to the top of the pnlToolBox.
What we see:
- with the standard resolution, the image in the emulator is still equal to the original layout.
- with the 240/320 resolution we see that the buttons are at the bottom of the screen but the
ListView height is shortened.
- with the 480/800 resolution we see that the buttons are at the bottom and the ListView is
higher.
The numbers of items in the ListView is different in the three layouts because the ListView height
has been adapted to the different relative screen heights.
In the first test, the number of items in the ListView were the same !
These examples show that it is not easy to have one layout for different screen resolutions.
In the example above it was relatively easy because the view in the middle is easily adjustable.
102
Even when we load the layout file in the three emulators with resolutions 480 / 800, 320 / 480 and
240 / 320 pixels the layout is stretched or compressed according to the screen size, but of course we
also see extra or missing pixels depending on the different relative screen heights.
The Android OS autoscale system adjusts the Left, Top, Width, Height, FontSize and other
properties with the scale factor but does NOT resize the vertical positions nor the heights of the
views proportional to the screen height. The same is valid for the width in landscape mode.
5.1
103
There are special functions to accommodate different screen sizes and resolution.
or
50%x
or
50dip
DipToCurrent calculates a dimension with the given Length according to the scale of the current
device.
DipToCurrent(50) is equal to 50 * DeviceScale
It can be written as a shortcut: 50dip density independent pixel
The 'standard' resolution is 160 dpi (dots per inch) and scale 1.
No spaces between the number and dip!
If we have a Button with a dimension of 50 * 50 pixels standard scale, to define its dimensions we
should set Button1.Width = 50dip and Button1.Height = 50dip.
Depending on the scale, the Button dimension will be:
Scale
Pixels
1
50 * 50
1.5
75 * 75
Example:
Dim Button1 As Button
Button1.Initialize("Button1")
Activity.AddView(Button1, 20%x, 30%y, 100dip, 50dip)
The values for the Left, Top, Width and Height properties in the Designer are considered as
dip values.
5.2
104
With the big number of devices, screen sizes, and resolutions on the market, it becomes more and
more complicated to design a project that looks nice on all available devices.
There is no universal method to manage this problem. The method you choose depends on :
What kind of project you are designing.
What devices and screen sizes you are targeting.
What you want to show on the different screens.
The same layout but stretched according to the screen sizes, or
Different layout variants for the different sizes. On a big screen more views can be
displayed at the same time.
Summary of the different physical screen sizes, where each size can have different resolutions,
densities scales and aspect ratios.
resolution density scale aspect ratio
~ 3.0'' - 4.0 ''
320 / 240
120 0.75 4 / 3
1.333
480 / 320
160 1
3/2
1.5
640 / 480
240 1.5
4/3
1.333
800 / 480
240 1.5
5/3
1.667
854 / 480
240 1.5
16 / 9 1.78
960 / 540
240 1.5
16 / 9 1.78
960 / 640
240 1.5
3/2
1.5
1280 / 720
320 2
16 / 9 1.78
~ 5.5 ''
1280 / 800
240 1.5
16 / 10 1.6
~ 7 ''
1024 / 600
160 1
1.71
1280 / 800
160 1
16 / 10 1.6
~ 10 ''
1024 / 600
160 1
1.71
1024 / 768
160 1
4/3
1.333
1280 / 800
160 1
16 / 10 1.6
1920 / 1200 240 1.5
16 / 10 1.6
Depending on what you want to display on the different screens you can either :
Design different layout variants.
Two layout variants (portrait and landscape) for each dimension.
The views are automatically resized for the different densities.
However, you may need to take into account different width/height ratios (aspect ratios).
These adjustment could be done in the code or would need two more layout variants.
Calculate all view dimensions and positions in the code using %x , %y and dip dimensions.
For comparison :
A 5.5'' screen has a surface about 2.5 times bigger than a 3.5'' screen.
A 7'' screen has a surface about 4 times bigger than a 3.5'' screen.
A 10'' screen has a surface about 9 times bigger than a 3.5'' screen.
105
The examples below show the same layout stretched in the code to fit the different screen sizes.
The source code is OneLayoutStretched, the images are Emulator screenshots.
It's probably not the best solution to have the same layout stretched for all screen sizes.
It could be more interesting to show more views on bigger screens.
106
107
lstTest.TwoLinesLayout.SecondLabel.Top = 12%x
lstTest.TwoLinesLayout.ItemHeight = 24%y
Else
wb = 100%x / 4
pnlToolbox.Left = 0
pnlToolbox.Width = 100%x
pnlToolbox.Height = wb
pnlToolbox.Top = 100%y - wb
btnTest1.Left = 0
btnTest1.Width = wb
btnTest1.Top = 0
btnTest1.Height = wb
.
lblTitle.Left = 10%x
lblTitle.Width = 80%x
lblTitle.Top = 0
lblTitle.Height = 100%x / 8
lstTest.Left = 5%x
lstTest.Width = 90%x
lstTest.Top = lblTitle.Height
lstTest.Height = pnlToolbox.Top - lstTest.Top
lstTest.TwoLinesLayout.Label.Height = 12%x
lstTest.TwoLinesLayout.Label.Top = 0
lstTest.TwoLinesLayout.SecondLabel.Height = 10%x
lstTest.TwoLinesLayout.SecondLabel.Top = 12%x
lstTest.TwoLinesLayout.ItemHeight = 22%x
End If
btnTest1.Text = "Test 1"
btnTest1.TextSize = 16 * TextSizeRatio
btnTest2.Text = "Test 2"
btnTest2.TextSize = 16 * TextSizeRatio
btnTest3.Text = "Test 3"
btnTest3.TextSize = 16 * TextSizeRatio
btnTest4.Text = "Test 4"
btnTest4.TextSize = 16 * TextSizeRatio
lblTitle.Text = "Test layout"
lblTitle.TextSize = 20 * TextSizeRatio
lstTest.TwoLinesLayout.Label.TextSize = 20 * TextSizeRatio
lstTest.TwoLinesLayout.Label.Gravity = Gravity.CENTER_VERTICAL
lstTest.TwoLinesLayout.Label.Color = Colors.Blue
lstTest.TwoLinesLayout.SecondLabel.TextSize = 16 * TextSizeRatio
lstTest.TwoLinesLayout.SecondLabel.Gravity = Gravity.CENTER_VERTICAL
lstTest.TwoLinesLayout.SecondLabel.Color = Colors.Green
End Sub
108
In the examples below we see the display of a grid with buttons. The physical button dimensions are
almost the same. The source code is CodeLayout.
3.5''
5.5''
10''
109
If you want to display more views on bigger screens you must define two layout variants (one for
portrait and one for landscape) for each screen size and resolution. This can become quite
cumbersome.
A compromise could be made by defining the layouts partly in the layout files and partly in the
code.
The adaptation of different aspect ratios could be done in the code rather than in separate layout
variants.
As already mentioned, there is no universal rule, the solution depends on different factors.
As a developer, you must define your needs and requirements as a function of :
What kind of project you are designing.
What kind of data you are treating, displaying, editing, etc.
What devices and screen sizes you are targeting.
What you want to show on the different screens.
The same layout, but stretched according to the screen size, or
Different layout variants for different sizes. On a big screen more views can be displayed
at the same time.
5.3
110
Screen orientations
In this line:
#SupportedOrientations: unspecified
Portrait
Phone1.SetScreenOrientation(1)
Both
Phone1.SetScreenOrientation(-1)
Both
5.4
111
There are several features in Basic4android (and Designer4android) that help you target Android
phones and tablets with different screen sizes and resolutions. The purpose of this page is to collect
tips and best practices that will help you create flexible layouts.
If you are not familiar with the designer script feature then please read this chapter
Designer Scripts
5.4.1 Advices
Below a few advices.
5.4.1.1 'dip' units
It is very simple. You should always use 'dip' units when specifying the size or position of a view
(control). This way the view's physical position and size will be the same on any device.
This is correct for both regular code and designer script.
Button1.Width = 100
'WRONG!
Button1.Width = 100dip 'Good job!
Note that text size is measured in physical units. So you should not use 'dip' units with text size
values.
5.4.1.2 Use only a few layout variants
It is easy to create many variants. However it is very difficult to maintain a layout made of many
variants. You should use the designer script feature to adjust (or fine tune) your layout instead of
creating many variants.
5.4.1.3 Understand the meaning of scale (dots per inch)
There are many questions starting with "I have a device with 480x800 screen...". There is no
meaning to these dimensions without the scale value.
A scale of 1.0 means that there are 160 dots (pixels) per inch.
The scale values can be one of the following values: 0.75, 1.0, 1.5, 2 and 3.
Most phones today have a scale of 1.5 (160 * 1.5 = 240 dots per inch).
Most tablets have a scale of 1.0, and some have a scale of 1.5.
5.4.1.4 "Normalized" variants
Normalized variants are variants with a scale of 1.0.
The layout you create with the designer is scaled (not stretched or resized) automatically. This
means that the layout will look exactly the same on two phones with the same physical size. The
scale doesn't matter.
It is highly recommended to work and design your layout with normalized variants only.
For example a variant of 480x800, scale=1.5 matches the normalized variant: 320x533, scale=1.0
(divide each value by the scale value). Now it is easy to see that this device is slightly longer than
the "standard" variant: 320x480, scale=1.0.
112
5.4.1.6 How to change the views size and text size? AutoScale
Larger devices offer a lot more available space. The result is that even if the physical size of a view
is the same, it just "feels" smaller.
Some developers use %x and %y to specify the views size. However the result is far from being
perfect. The layout will just be stretched.
The solution is to combine the "dock and fill" strategy with a smart algorithm that increases the
views size and text size based on the running devices physical size.
We treat the standard variant (320 x 480, scale = 1.0) as the base variant. We then use this script
code to calculate the scale factor:
delta = ((100%x + 100%y) / (320dip + 430dip) - 1)
rate = 0.3 'value between 0 to 1.
scale = 1 + rate * delta
You can play with the value of 'rate'. The rate determines the change amount in relation to the
device physical size.
Value of 0 means no change at all. Value of 1 is similar to using %x and %y: If the physical size is
twice the size of the standard phone then the size will be twice the original size.
Values between 0.2 to 0.5 seem to give good results.
The abstract designer is useful to quickly test the effect of this value.
The scale will not be applied automatically.
You will need to manually do it (for the views that need to adjust their size):
Label1.TextSize = Label1.TextSize * scale
Button1.Width = Button1.Width * scale
'For a button that is docked to the right side:
Button2.Width = Button2.Width * scale
Button2.Right = 100%x
'Or:
Button2.SetLeftAndRight(100%x - Button2.Width * scale, 100%x)
6 The Emulator
113
The Emulator
The Emulator or Virtual Device is a program that simulates devices on the PC.
6.1
Launch an Emulator
To launch an Emulator click in the IDE in the Tools menu
on Run AVD Manager.
Click on
6 The Emulator
114
Wait until the Emulator is ready, this will take quite some time.
The physical size of the Emulator on the screen can be changed in the Launch Option window.
6 The Emulator
6.2
115
Let us add a new Emulator with a resolution of 480 / 800 pixels, density 240.
In the AVD Manager
Click
SD Card:
Enter 16.
Skin: select WVGA800.
HVGA
QVGA
WQVGA400
WQVGA432
WVGA800
WVGA854
Click
320 / 480
240 / 320
240 / 400
240 / 432
480 / 800
480 / 854
6 The Emulator
116
Click
Click
Click
6 The Emulator
The new Emulator is added.
117
6 The Emulator
6.3
118
Emulator problems
In most cases, if you run the program once more, the connection to the Emulator will be established
and it will work properly.
This often happens when the Emulator is still running a program or if the Emulator is still
connected to another project. In this case press the back button until you reach the Emulator's home
screen and try again.
If this happens for a second time, close the current Emulator and run it again from the AVD
Manager.
If the first message above appears too often you can increase the process timeout value.
6 The Emulator
119
6 The Emulator
6.4
120
To get access to files in the Emulator you can use the Dalvik Debug Monitor.
The name is ddms.bat and it is located in the folder where you copied the Android SDK.
Example : C:\Android\android-sdk-windows\tools.
Make sure that Emulator is running.
Run the ddms.bat file:
Wait a moment.
6 The Emulator
121
mnt\sdcard
is the
DirRootExternal
folder.
In the example the
file persons.db is a
database copied in a
B4A program from
DirAssets to
DirRootExternal.
6 The Emulator
122
If the Dalvik Debug Monitor doesn't run you need to add the path where the ddms.bat file is located
to the environment variables.
From the desktop, right-click My Computer and click Properties.
In the System Properties window, click on the Advanced tab.
In the Advanced section, click the Environment Variables button.
Finally, in the Environment Variables window (as shown below), highlight the Path variable in
the Systems Variable section and click the Edit (Modifier) button. Add or modify the path lines
with the paths you wish the computer to access. Each different directory is separated with a
semicolon as shown below.
123
7.1
USB
You should download Google USB Driver in the Android SDK Manager.
If this driver doesn't work you must search for a specific driver for your device.
To be able to connect a device with USB you must activate USB Debugging.
This is also need if you use an Emulator.
In this state on most devices you will not be able to access the SD card from the PC.
If you want to access the SD card you must uncheck USB Debugging.
Launch Settings
Select Applications
Select Development
7.2
124
B4A Bridge
Up until now there were two methods for testing your application during development.
You can either work with the Android emulator or if your device supports ADB debugging, you are
able to connect to your real device.
The Android emulator is very slow compared to a real device (especially with applications
installation).
Therefore in most cases it is more convenient to work with a real device.
Personally, I'm only using the emulator when working with the visual designer.
However not all devices support ADB debugging. This is exactly the reason for the new B4ABridge tool.
B4A-Bridge is made of two components. One component runs on the device and allows the second
component which is part of the IDE to connect and communicate with the device.
The connection is done over a network (B4A-Bridge cannot work if there is no network available).
Once connected, B4A-Bridge supports all of the IDE features which include: installing applications,
viewing LogCat and the visual designer.
Android doesn't allow applications to quietly install other applications, therefore when you run your
application using B4A-Bridge you will see a dialog asking for your approval.
Getting started with B4A-Bridge
125
You should now choose either Start - Wireless or Start - Bluetooth depending on the working mode.
The Make Discoverable checkbox will make your device Bluetooth discoverable for 5 minutes.
This is only needed if the device and computer weren't paired before.
126
In Bluetooth mode you should first click on Find Devices. All paired devices and new devices in
discoverable mode will be listed.
You should choose the correct one and press on Connect.
Assuming that the connection succeeded the dialog will be closed.
The status bar at the bottom of the screen shows the current status:
or
That's it.
When B4A-Bridge gets connected it first checks if the designer application needs to be updated. In
that case it will first install the designer application.
B4A-Bridge keeps running as a service until you press on the Stop button.
You can always reach it by opening the notifications screen:
127
Note that the Bluetooth permission and Internet permission are automatically added in debug mode.
128
In the above dialog you should choose Open to start the application.
If you try to install an existing application signed with a different key, the install will fail
(without any meaningful message). You should first uninstall the existing application. Go to
the home screen - Settings - Applications - Manage applications - choose the application Uninstall.
Once you finished developing you should press on the Stop button in order to save battery.
7.2.3.3 Bluetooth tips
- Unfortunately many devices, especially older devices running Android 2.1 or 2.2 have all kinds of
issues with Bluetooth connections and especially with multiple connections. All kinds of
workarounds were implemented because of these issues. Still however there are devices (HTC
desire for example) that do not work reliably enough.
- The Reset Bluetooth button disables and then enables the Bluetooth adapters. You should try it if
there are connections problems.
- If your connection is not stable then you should avoid using the debugger or designer. Both the
debugger and the designer create an additional connection.
Note that B4A-Bridge was written with Basic4android.
8 The Designer
129
The Designer
The Designer allows generating layouts with either the Emulator or a real device.
8.1
130
The menu
New
Open
Save
Save As
Remove Layout
Removes the layout from the Files directory.
Main
Layout file list, in this case only one file, 'Main'.
131
AutoCompleteEditText
adds an AutoCompleteEditText
Button
adds a Button
CheckBox
adds a CheckBox
CustomView
adds a CustomView
EditText
adds an EditText
ImageView
adds an ImageView
HorizontalScrollViewadds a HorizontalScrollView
Label
adds a Label
ListView
adds a ListView
Panel
adds a Panel
ProgressBar
adds a ProgressBar
RadioButton
adds a RadioButton
ScrollView
adds a Scrollview
SeekBar
adds a SeekBar
Spinner
adds a Spinner
TabHost
adds a TabHost
ToggleButton
adds a ToggleButton
WebView
adds a WebView
132
Generate Members
Bring to Front
Members generator
Brings the selected View to front
Send To Back
Sends the selected View to back
Duplicate Selected View Duplicates the selected View
Remove Selected View Removes the selected View
Change Grid
8.2
133
Tools
Clicking on an event
Sub btnAction_Click
End Sub
Click on
134
is
the opposite of Bring To Front.
135
Click on
You can change the grid size
to the value you want.
The value is saved in the layout file, you will get the same value when you reload this layout.
The default value when you start a new project is 10.
136
If different devices or Emulators are connected, you will be asked which device or Emulator you
want to connect to.
Click on
To disconnect it click on
to confirm.
8.3
137
General settings
Shows the Designer state. You can add views, remove views and edit their properties.
In the left pane all views are displayed in a tree.
In the middle pane the properties of the selected view are displayed and can be edited.
On the right part of the screen several settings can be set.
A parent view like the Activity or a Panel can be expanded or not.
138
8.4
139
Image files
You can add image files to the layout.
Click on
8.5
140
Properties list
Main :
Name
Name of the view. It is good practice to give meaningful names. Common
usage is to give a 3 character prefix and add the purpose of the view. In the example, the view is of
type Label and its purpose is to enter a result. So we give it the name "lblResult", "lbl" for
Label and "Result" for the purpose. This does not take much time during the design of the layout
but saves a lot time during coding and maintenance of the program.
Type
Type of the view, not editable. It is not possible to change the type of a view.
If you need to, you must remove the view and add a new one.
Event Name
Generic name for the subroutines that manages the view's events. By default,
the Event Name is the same as the view's name like in the example. The Events of several Views
can be redirected to a same subroutine. In that case you must enter the name of that routine.
Look at the SecondProgram example for the Click event management for the buttons of the
keyboard, the btnEvent_Click routine.
Parent
Name of the parent view. Activity, in the example. The parent view can be
changed in selecting the new one in the list.
141
Common properties :
HorizontalAnchor Horizontal Anchor function. Possible values LEFT, RIGHT or BOTH
VerticalAnchor
Left
X coordinate of the left edge of the View from the left edge of its parent
View, in pixels (the pixels are in reality dips, density independent pixels).
Top
Y coordinate of the upper edge of the View from the upper edge of its parent
View, in pixels (the pixels are in reality dips, density independent pixels).
Width
Width of the View in pixels (the pixels are in reality dips, density
independent pixels).
Height
Height of the View in pixels (the pixels are in reality dips, density
independent pixels).
Enabled
Visible
Tag
This is a place holder which can used to store additional data. Tag can simply
be text but can also be any other kind of object.
Tag is used in the SecondProgram example for the numeric buttons click events management in the
btnEvent_Click routine.
8.6
142
Layout variants
Different layout variants can be managed in a same layout file.
143
Select:
480 x 320
scale = 1
Click on
144
Button height 65
ListView1:
Width = 380
Height = 220
145
to
146
We can achieve a similar effect in the Designer when a different Layout Variant is selected and we
switch to Landscape mode (Ctrl-F11).
8.7
147
The Abstract Designer is a tool that shows the layout in a separate window and is part of the
Designer. It is much faster than the Emulator.
Its main purpose is to create different layout variants.
The different views are not shown with their exact shape but only as coloured rectangles.
Clicking on a view shows its properties in the Designer.
Emulator
Abstract Designer
148
Matches :
The chosen variant in the
Designer.
The connected device.
Zoom
Two possibilities:
50%
100%
Tools
Resize form to fit the layout.
Adds the current layout as a new layout variant in the
Designer.
149
Add View
Cut
Copy
Paste
Duplicate Selected Views
Horizontal Anchor
Vertical Anchor
Bring To Front
Send To Back
Generate
Generate : Generates the Dim statement or an event routine for the select View
Dim btnTest As Button
Generates the Dim statement
Dim btnTest1 As Button
Down
Generates the Down event
Sub btnTest1_Down
End Sub
Up
Generates the Up event
Sub btnTest1_Up
End Sub
Sub
btnTest1_Click
End Sub
LongClick
Generates the LongClick event
Sub btnTest1_LongClick
End Sub
150
Bring To Front.
Send To Back.
151
8.7.4 Example
Let us take a simple example with a layout in portrait mode, like the image below.
152
153
8.8
154
It is also possible to add views by code instead of using the Designer with a device, the Emulator or
the Abstract Designer.
Advantage : you have full control of the view.
Disadvantage : you have to define almost everything.
The source code is in the source code directory: AddViewsByCode
For the positions and dimensions of the views on the screen two special options are available:
dip
density independent pixels.
100dip = DipToCurrent(100)
DipToCurrent is a Keyword
dip is the Shortcut
100dip = 100 / 160 * device density
The default density is 160 dpi dots per inch (pixels per inch)
Densities in Android:
o 120 scale 0.75
o 160 scale 1 default
o 240 scale 1.5
o 320 scale 2
%x and %y represent distances proportional to the active screen width and height.
20%x = 0.2 * Activity.Width
90%y = 0.9 * Activity.Height
20%x = PerXToCurrent(20)
PerXToCurrent is a Keyword %x is the Shortcut
90%y = PerYToCurrent(90)
Example:
Let us put a Label on top of the screen and a Panel below it with a Label and a Button on it:
Sub Globals
Dim lblTitle, lblPanelTitle As Label
Dim pnlTest As Panel
Dim btnTest As Button
End Sub
155
btnTest.Initialize("btnTest")
btnTest.Text = "Test"
lblPanelTitle.Initialize("")
156
lblPanelTitle.Color = Colors.Red
lblPanelTitle.TextSize = 16
lblPanelTitle.TextColor = Colors.Blue
lblPanelTitle.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
lblPanelTitle.Text = "Panel test"
Adds the Label lblPanelTitle to the Panel pnlTest at the given position and with the given
dimensions in dips.
pnlTest.AddView(btnTest, 50dip, 50dip, 100dip, 60dip)
Adds the Button btnTest to the Panel pnlTest at the given position and with the given dimensions in
dips.
And the result:
8.9
157
Designer Scripts
One of the most common issues that Android developers face is the need to adapt 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.
158
How to
Every layout file can include script code. The script is written inside the visual designer under the
new Designer Scripts tab:
There 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.
159
Example
In this example we will build the following layout:
The source code is in the DesignerScripts folder.
160
The result:
161
162
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 use '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 : AutoScale(Button1)
- AutoScaleAll - Autoscales all layout views.
- AutoScaleRate - Sets the scaling rate, a value between 0 to 1. The default value is 0.3
Example : AutoScaleRate(0.5)
- 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.
163
If you write the beginning of a keyword of a view name and press Ctrs + Space you get the list of
available functions and views :
Example : Auto Ctrl + Space
164
8.10 Anchors
Two anchor properties, Horizontal Anchor and Vertical Anchor were added to
Basic4Androd version 3.20.
Horizontal Anchor
LEFT
This is the default value.
The left edge is anchored to the left
edge of the parent view with the
distance given in the Left property.
RIGHT
BOTH
Both edges are anchored.
The Width property is no more
available because it is defined by the
anchors !
Setting the Horizontal Anchor property to BOTH is similar to the SetLeftAndRight function in the
Designer Scripts.
165
Vertical Anchor
BOTTOM
The bottom edge is anchored to the bottom edge of
the parent view with the distance given in the Bottom
Edge Distance property.
The Top property is no more available because it is
defined by the Height and the bottom anchor !
BOTH
Both edges are anchored.
The Height property is no more
available because it is defined by the
anchors !
Setting the Vertical Anchor property to BOTH is similar to the SetTopAndBottom function in the
Designer Scripts.
166
What happens when we set the horizontal anchor of the two views below to BOTH and change the
parent view width?
The left views right edge is anchored to the right edge of the parent view with the Right Edge
Distance.
The right views left edge is anchored to the left edge of the parent view with the Left distance.
If we increase the width of the parent view we get the layout below.
The left views right edge is still at the Right Edge Distance from the parent views right edge.
The right views left edge is still at the Left distance from the parent views left edge.
The result is an overlapping of both views.
In this case you must adjust the views in the Designer Scripts with the SetLeftAndRight method!
For example:
LeftView.SetLeftAndRight(0, 67%x)
RightView.SetLeftAndRight(33%x, 100%x)
167
Click on Label.
168
of
169
170
The properties
Left = 10 and
Top = 10 remain the same.
Right Edge Distance = 10 and
Bottom Edge Distance = 10
171
And the result looks like the pictures below in portrait and landscape screen orientations.
To demonstrate the anchor feature we move, in the Abstract Designer, the top edge of Panel1
upwards.
172
173
In the code we :
- Load the layout.
- Fill the ListView and the ScrollView.
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Main")
FillListView
FillScroolView
End Sub
174
The anchors are valid in the AbstractDesigner but not in Designer Scripts.
For ListView1 its enough to set its Width property.
But for ScrollView1 we need to define both properties Left and Right which is done with
SetLeftAndRight because the RIGHT anchor is lost.
175
Click on btnRight.
property
to RIGHT.
176
Click on btnDown.
Set the
Horizontal Anchor
property
to BOTH.
Set the
Vertical Anchor property
to BOTTOM.
Click on EditText1.
Click on ListView1
Move the right edge to the right edge of the screen
177
Remains ToggleButton1.
For this view we need the DesignerScript we cannot adjust it with anchors.
178
8.11 AutoScale
Since B4A version 2.2 three new functions have been added :
AutoScaleRate(rate)
AutoScale
AutoScaleAll
Larger devices offer a lot more available space. The result is that even if the physical size of a view
is the same, it just "feel" smaller.
Some developers use %x and %y to specify the views size. However the result is far from being
perfect. The layout will just be stretched.
The solution is to combine the "dock and fill" strategy with a smart algorithm that increases the
views size and text size based on the running device physical size.
The AutoScale function is based on the standard variant (320 x 480, scale = 1.0).
Since Basic4Android version 3.2 AutoScale takes into account the dimensions of the variant
defined in the layout.
For other screen sizes and resolutions AutoScale calculates a scaling factor based on the equations
below.
delta = ((100%x + 100%y) / (320dip + 430dip) - 1)
rate = 0.3 'value between 0 to 1.
scale = 1 + rate * delta
AutoScale multiplies the Left / Top / Width and Height properties by the scale value.
If the view has a Text property this one is also multiplied by the scale value.
You can play with the 'rate' value. The rate determines the change amount in relation to the device
physical size.
Value of 0 means no change at all. Value of 1 is almost similar to using %x and %y: If the physical
size is twice the size of the standard phone then the size will be twice the original size.
Values between 0.2 to 0.5 seem to give good results. The default value is 0.3.
Be careful when you downsize a layout defined for a big screen to a small screen. The views may
become very small.
Note: The size of the CheckBox and RadioButton images is the same for all screen sizes.
The abstract designer is useful to quickly test the effect of this value.
Functions :
AutoScaleRate(rate) Sets the rate value for above equations.
Example : AutoScaleRate(0.5) Sets the rate value to 0.5.
AutoScale(View)
Scales the given view.
Example : AutoScale(btnTest1)
This is quivalent to :
btnTest1.Left = btnTest1.Left * scale
btnTest1.Top = btnTest1.Top * scale
btnTest1.Width = btnTest1.Width * scale
btnTest1.Height = btnTest1.Height * scale
btnTest1.TextSize = btnTest1.TextSize * scale
AutoScaleAll
179
We have :
2 Labels on the top of the screen :
o lblTitle
o lblSubTitle
We have two layout files Main for the main screen and Panel for the ScrollView content with only
one layout variant 320 x 480 scale = 1 (160dip) for each.
180
and we set the Vertical Anchor property of the ToolBox to BOTTOM to anchor it to the bottom of
the screen with :
This is needed because not all screens have the same width / height ratio and in landscape
orientation it would even not be visible.
Then we set the Vertical Anchor property of the ScrollView to BOTH because we want it to fill the
space between lblSubTitle and pnlToolBox.
We set the Bottom Edge Distance property to 60 to leave a small space of 10dip between the
ScrollView and the ToolBox.
Code in the Designer Scripts of the Main layout in the area for All variants script :
'All variants script
'Set the rate value to 0.5
AutoScaleRate(1)
'Scale all the views in the layout
AutoScaleAll
'Center the Labels horizonally to the middle of the screen
lblTitle.HorizontalCenter = 50%x
lblSubTitle.HorizontalCenter = 50%x
'Center the ToolBox Panel horizonally to the middle of the screen
pnlToolBox.HorizontalCenter = 50%x
'Center the ScrollView horizonally to the middle of the screen
scvTest.HorizontalCenter = 50%x
181
Code in the Designer Scripts of the Panel layout in the area for All variants script :
The whole code is very simply :
'All variants script
AutoScaleRate(0.5)
AutoScaleAll
We load the Main layout file into the Activity with Activity.LoadLayout("Main").
We load the Panel layout file into the ScrollView with scvTest.Panel.LoadLayout("Panel").
We set the ScrollView.Panel.Height to the height of the Panel in the layout file with :
scvTest.Panel.Height = pnlSetup.Height
182
Rate = 0
Rate = 0.5
Rate = 0.1
Rate = 0.7
Rate = 0.3
Rate = 1.0
183
Rate = 0
Rate = 0.1
Rate = 0.3
Rate = 0.5
Rate = 0.7
Rate = 1
Screenshots of a 320/480 3.5'' screen Emulator. The Rate value has no influence.
184
8.11.2 Same AutoScale example with portrait and landscape layout variants
Source code AutoScaleExample2 :
185
For the landscape variant we have in the All variants script area the same code as for the
portrait variant :
'All variants script
AutoScaleRate(0.5)
AutoScaleAll
We center the ToolBox vertically to the middle of the screen height with :
pnlToolBox.VerticalCenter = 50%y
We set the right border of the ToolBox to right border of the screen with :
pnlToolBox.Right= 100%x
We set the Vertical Anchor property of the ScrollView to BOTH to fill the space between the
bottom SubTitle Label boarder and the bottom screen boarder with.
186
187
188
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.
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.
189
On the following pages you'll see some screenshots of following Emulators with Rate = 0.5 :
1280 x 800 10'' tablet
Main :
Setup :
About :
190
DBWebView :
DBScrollView :
Keyboard :
191
8.12 UI Cloud
Since Basic4Android version 2.30 a new feature allowing to see how layouts look on different
devices.
192
193
9.1
194
How do we handle it ?
When you create a new activity you will start with the following code template:
'Activity module
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
End Sub
Sub Activity_Create(FirstTime As Boolean)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Variables can be either global or local. Local variables are variables that are declared inside a sub
other than Process_Globals or Globals.
Local variables are local to the containing sub. Once the sub ends, these variables no longer exist.
Global variables can be accessed from all subs.
There are two types of global variables.
Process variables and activity variables.
9.2
195
9.3
Activity variables
9.4
9.5
196
9.6
Sub Activity_Resume
Sub Activity_Pause (UserClosed As Boolean)
Each time the activity moves from the foreground to the background Activity_Pause is called.
Activity_Pause is also called when the activity is in the foreground and a configuration change
occurs (which leads to the activity getting paused and then destroyed).
Activity_Pause is the last place to save important information.
Generally there are two types of mechanisms that allow you to save the activity state.
Information that is only relevant to the current application instance can be stored in one or more
process variables.
Other information should be stored in a persistent storage (file or database).
For example, if the user changed some settings you should save the changes to a persistent storage
at this point. Otherwise the changes may be lost.
Activity_Resume is called right after Activity_Create finishes or after resuming a paused activity
(activity moved to the background and now it returns to the foreground).
Note that when you open a different activity (by calling StartActivity), the current activity is first
paused and then the other activity will be created if needed and (always) resumed.
As discussed above Activity_Pause is called every time the activity moves from the foreground to
the background. This can happen because:
1. A different activity was started.
2. The Home button was pressed.
3. A configuration changed event was raised (orientation changed for example).
4. The Back button was pressed.
In scenarios 1 and 2, the activity will be paused and for now kept in memory as it is expected to be
reused later.
In scenario 3 the activity will be paused, destroyed and then created (and resumed) again.
In scenario 4 the activity will be paused and destroyed. Pressing on the Back button is similar to
closing the activity. In this case you do not need to save any instance specific information (the
position of pacman in a PacMan game for example).
The UserClosed parameter will be true in this scenario and false in all other. Note that it will also be
true when you call Activity.Finish. This method pauses and destroys the current activity, similar to
the Back button.
You can use UserClosed parameter to decide which data to save and also whether to reset any
related process variables to their initial state (move pacman position to the center if the position is a
process variable).
9.7
197
Activity.Finish / ExitApplication
198
Type
boolean
Byte
integer 8 bits
Short
integer 16 bits
Int
integer 32 bits
Long
Float
Double
double precision
number
64 bits
Char
String
character
array of characters
min value
False
- 27
-128
- 2 15
- 32768
- 2 31
-2147483648
- 2 63
max value
True
27 - 1
127
2 15 -1
32767
2 31 -1
2147483647
2 63 -1
-9223372036854775808
9223372036854775807
-149
-2
1.4E-45
- 2 -1074
(2 -2 -23) * 2 127
3.4028235 E 38
(2 -2 -52) * 2 1023
2.2250738585072014 E 308
1.7976931348623157 E
308
Primitive types are always passed by value to other subs or when assigned to other variables.
For example:
Sub S1
Dim A As Int
A = 12
S2(A)
Log(A) ' Prints 12
End Sub
Sub S2(B As Int)
B = 45
End Sub
The variable A = 12
It's passed by value to routine S2
Variable A still equals 12, even though B was changed in routine S2.
Variable B = 12
Its value is changed to B = 45
199
All other types, including arrays of primitives types and strings are categorized as non-primitive
types.
When you pass a non-primitive to a sub or when you assign it to a different variable, a copy of the
reference is passed.
This means that the data itself isn't duplicated.
It is slightly different than passing by reference as you cannot change the reference of the original
variable.
All types can be treated as Objects.
Collections like lists and maps work with Objects and therefore can store any value.
Here is an example of a common mistake, where the developer tries to add several arrays to a list :
Dim arr(3) As Int
Dim List1 As List
List1.Initialize
For i = 1 To 5
arr(0) = i * 2
arr(1) = i * 2
arr(2) = i * 2
List1.Add(arr) 'Add the whole array as a single item
Next
arr = List1.Get(0) 'get the first item from the list
Log(arr(0))
'What will be printed here???
200
10.3
Declaring variables
Dim i As Int
Dim j As Int
Dim k As Int
The names of the variables separated by commas and followed by the type declaration.
201
View names must be declared when we want to use them in the code.
For example, if we wan to change the text in an EditText view in the code, like
edtCapital.Text = "1200",
we need to reference this EditText view by its name edtCapital, this is done with the Dim
declaration.
If we never make any reference to this EditText view anywhere in the code no declaration is
needed.
Using an event routine for that view doesn't need a declaration either.
To allocate a value to a variable write its name followed by the equal sign and followed by the
value, like:
Capital = 1200
LastName = "SMITH"
Note that for Capital we wrote just 1200 because Capital is a number.
But for LastName we wrote "SMITH" because LastName is a string.
Strings must always be written between double quotes.
The last index is equal to the number of items in each dimension minus 1.
LastName(49), Matrix(2,2), Data(2,4,9)
Dim
Dim
Dim
Dim
LastName(10) As String
FirstName(10) As String
Address(10) As String
City(10) As String
or
Dim LastName(10), FirstName(10), Address(10), City(10) As String
202
This example shows how to access all items in a three dimensional array.
For i = 0 To 2
For i = 0 To 2
For i = 0 To 2
Data(i, j, k) = ...
Next
Next
Next
NbPers As Int
: NbPers = 10
LastName(NbPers) As String
FirstName(NbPers) As String
Address(NbPers) As String
City(NbPers) As String
We declare the variable Dim NbPers As Int and set its value to 10, NbPers = 10 .
The semi-colon ":" is a separator for two statement on the same line.
Then we declare the arrays with this variable instead of the number 10 as before.
The big advantage is if at some point we need to change the number of items, we change only ONE
value.
For the Data array we could use the following code.
Dim
Dim
Dim
Dim
NbX As Int
: NbX
NbY As Int
: NbY
NbZ As Int
: NbZ
Data(NbX, NbY, NbZ) As
= 2
= 5
= 10
Int
203
The Buttons could also have been added in a layout file, in that case they must neither be initialized,
nor added to the Activity and the Text and Tag properties should also be set in the Designer.
In that case the code would look like this:
Sub Globals
Dim b1, b2, b3, b4, b5, b6, b7 As Button
Dim Buttons() As Button
End Sub
Sub Activity_Create(FirstTime As Boolean)
Dim i As Int
Buttons = Array As Button(b1, b2, b3, b4, b5, b6, b7)
End Sub
Sub Buttons_Click
Dim btn As Button
btn = Sender
Activity.Title = "Button " & btn.Tag & " clicked"
End Sub
204
The new personal type is Person , then we declare either single variables or arrays of this personal
type.
To access a particular item use following code.
CurrentUser.FirstName
CurrentUser.LastName
User(1).LastName
User(1).FirstName
10.4
205
Casting
Basic4android casts types automatically as needed. It also converts numbers to strings and vice
versa automatically.
In many cases you need to explicitly cast an Object to a specific type.
This can be done by assigning the Object to a variable of the required type.
For example, Sender keyword references an Object which is the object that raised the event.
The following code changes the color of the pressed button.
Note that there are multiple buttons that share the same event sub.
Sub Globals
Dim Btn1, Btn2, Btn3 As Button
End Sub
Sub Activity_Create(FirstTime As Boolean)
Btn1.Initialize("Btn")
Btn2.Initialize("Btn")
Btn3.Initialize("Btn")
Activity.AddView(Btn1, 10dip, 10dip, 200dip, 50dip)
Activity.AddView(Btn2, 10dip, 70dip, 200dip, 50dip)
Activity.AddView(Btn3, 10dip, 130dip, 200dip, 50dip)
End Sub
Sub Btn_Click
Dim btn As Button
btn = Sender
' Cast the Object to Button
btn.Color = Colors.RGB(Rnd(0, 255), Rnd(0, 255), Rnd(0, 255))
End Sub
10.5
206
Scope
' public
' private
' public like Public
207
10.6
Tips
A view can be assigned to a variable so you can easily change the common properties of the view.
For example, the following code disables all views that are direct children of the activity:
For i = 0 To Activity.NumberOfViews - 1
Dim v As View
v = Activity.GetView(i)
v.Enabled = False
Next
11 Modules
208
11 Modules
At least one module exists, the main one.
Its name is always Main and cannot be changed.
To add an existing module click on Add Existing Module in the IDE menu Project.
11 Modules
11.1
209
Activity modules
Each Activity has its own module. For a better knowledge of Activity life cycle have a look at the
Process and Activity life cycle chapter.
You can add either an existing module or a new module.
To add a new Activity module click on:
To access these variables from another module the name is Main.Value1 or Main.Value2.
Sub Activity_Pause (UserClosed As Boolean)
Main.Value2 = edtValue2_P2.Text ' Sets edtValue_P2.Text to the
End Sub
' Process Global variable Value2
It is NOT possible to access any view from another activity module, because when a new activity is
started the current activity is paused and its no more accessible !
11 Modules
210
11 Modules
11.3
211
Code modules
11 Modules
11.4
212
Service modules
Service modules play an important role in the application and process life cycle.
Start with this tutorial if you haven't read it before: Android Process and activities life cycle
Code written in an activity module is paused once the activity is not visible.
So by only using activities it is not possible to run any code while your application is not visible.
Services life cycle is (almost) not affected by the current visible activity. This allows you to run
tasks in the background.
Services usually use the status bar notifications to interact with the user. Services do not have any
other visible elements. Services also cannot show any dialog (except of toast messages).
Note that when an error occurs in a service code you will not see the "Do you want to continue?"
dialog. Android's regular "Process has crashed" message will appear instead.
Before delving into the details I would like to say that using services is simpler than it may first
sound. In fact for many tasks it is easier to work with a service instead of an activity as a
service is not paused and resumed all the time and services are not recreated when the user rotates
the screen. There is nothing special with code written in service.
Code in a service module runs in the same process and the same thread as all other code.
It is important to understand how Android chooses which process to kill when it is low on memory
(a new process will later be created as needed).
A process can be in one of the three following states:
- Foreground - The user currently sees one of the process activities.
- Background - None of the activities of the process are visible, however there is a started service.
- Paused - There are no visible activities and no started services.
Paused processes are the first to be killed when needed. If there is still not enough memory,
background processes will be killed.
Foreground processes will usually not be killed.
As you will soon see a service can also bring a process to the foreground.
Adding a service module is done by choosing Project - Add New Module - Service Module.
11 Modules
213
Sub Process_Globals is the place to declare the service global variables. There is no other Globals
sub like in Activity as Service doesn't support Activity objects.
Sub process globals should only be used to declare variables. It should not run any other code as it
might fail. This is true for other modules as well.
Note that Process_Global variables are kept as long as the process runs and are accessible from
other modules.
Sub Service_Create is called when the service is first started. This is the place to initialize and set
the process global variables. Once a service is started it stays alive until you call StopService or
until the whole process is destroyed.
Sub Service_Start is called each time you call StartService (or StartServiceAt). When this subs
runs the process is moved to the foreground state. Which means that the OS will not kill your
process until this sub finishes running. If you want to run some code every couple of minutes /
hours you should schedule the next task with StartServiceAt inside this sub.
Sub Service_Destroy is called when you call StopService. The service will not be running after this
sub until you call StartService again (which will run Sub Service_Create followed by Sub
Service_Start).
Service use cases
As I see it there are four main use cases for services.
- Separating UI code with "business" or logic code. Writing the non-UI code in a service is easier
than implementing it inside an Activity module as the service is not paused and resumed and it is
usually will not be recreated (like an Activity).
You can call StartService during Activity_Create and from now on work with the service module.
A good design is to make the activity fetch the required data from the service in Sub
Activity_Resume. The activity can fetch data stored in a process global variable or it can call a
service Sub with CallSub method.
- Running a long operation. For example downloading a large file from the internet. In this case you
can call Service.StartForeground (from the service module). This will move your activity to the
foreground state and will make sure that the OS doesn't kill it. Make sure to eventually call
Service.StopForeground.
11 Modules
214
- Scheduling a repeating task. By calling StartServiceAt you can schedule your service to run at a
specific time. You can call StartServiceAt in Sub Service_Start to schedule the next time and create
a repeating task (for example a task that checks for updates every couple of minutes).
- Run a service after boot. By checking Project - Service properties - Run At Boot your service will
run after boot is completed.
Notifications
Status bar notifications can be displayed by activities and services.
Usually services use notifications to interact with the user. The notification displays an icon in the
status bar. When the user pulls the status bar they see the notification message.
The notification icon is an image file which you should manually put in the following folder:
<project folder>\Object\res\drawable.
Accessing other modules
Process global objects are public and can be accessed from other modules.
Using CallSub method you can also call a sub in a different module.
It is however limited to non-paused modules. This means that one activity can never access a sub of
a different activity as there could only be one running activity.
However an activity can access a running service and a service can access a running activity.
Note that if the target component is paused then an empty string returns.
No exception is thrown.
You can use IsPause to check if the target module is paused.
For example if a service has downloaded some new information it can call:
If the Main activity is running it will fetch the data from the service process global variables and
will update the display.
It is also possible to pass the new information to the activity sub. However it is better to keep the
information as a process global variable. This allows the activity to call RefreshData whenever it
want and fetch the information (as the activity might be paused when the new information arrived).
Note that it is not possible to use CallSub to access subs of a Code module.
Examples:
Downloading a file using a service module
Periodically checking Twitter feeds
11 Modules
215
You can see that a module was loaded from the shared folder in the list of modules:
Adding a shared module to a project is done in the same way as adding a non-shared module.
You choose Project -> Add Existing Module. If the module folder is the shared folder then the
module will be loaded as a shared module and will not be copied to the project folder.
If you want to convert a non-shared module to a shared module then you need to manually move the
module file to the shared modules folder and reload the project
12 Tools
216
12 Tools
To find answers to many questions about Basic4Android the following tools are very useful.
12 Tools
217
12 Tools
218
12.3 B4AHelp
B4AHelp is a stand alone program written by Andrew Graham (agraham) showing the help files for
the diffferent libraries. It can be downloaded here.
On top we find :
12 Tools
219
Standard libraries
(Open).
Here
you can select the directory where the
standard libraries are saved.
Once selected the directory is saved for the next start of the program.
12 Tools
220
Additional libraries.
The same also for the additional libraries.
Here
additional libraries.
Core
12 Tools
221
12 Tools
222
Design
Developp
Distribute
12 Tools
223
12.6 Books
Basic4Android book
Written by Philip Brown under the pseudo Wyken Seagrave.
http://basic4android.info/
http://www.magbooks.com/mag-books/
13 Example programs
224
13 Example programs
13.1
User interfaces
Let us make three different user interfaces to select three different screens.
The three user interfaces are:
Menu
TabHost view
Button toolbox
For each of the three pages there are separate layout files Page1, Page2 and Page3.
Each layout file is loaded to a Panel or a TabHost panel.
These layouts can contain whatever views you need.
13 Example programs
225
Sub Globals
Dim pnlPage1, pnlPage2, pnlPage3 As Panel
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Main")
pnlPage1.Initialize("")
pnlPage1.LoadLayout("Page1")
Activity.AddView(pnlPage1,0,0,100%x,100%y)
pnlPage1.Visible=True
'
'
'
'
Initializes pnlPage1
Loads "Page1" layout file
Adds pnlPage1 to Activity
Sets pnlPage1 to Visible
pnlPage2.Initialize("")
pnlPage2.LoadLayout("Page2")
Activity.AddView(pnlPage2,0,0,100%x,100%y)
pnlPage2.Visible=False
'
'
'
'
Initializes pnlPage2
Loads "Page2" layout file
Adds pnlPage1 to Activity
Sets pnlPage1 to Visible
pnlPage3.Initialize("")
pnlPage3.LoadLayout("Page3")
Activity.AddView(pnlPage3,0,0,100%x,100%y)
pnlPage3.Visible=False
'
'
'
'
Initializes pnlPage3
Loads "Page3" layout file
Adds pnlPage1 to Activity
Sets pnlPage1 to Visible
Activity.AddMenuItem("Page 1","mnuPage1")
Activity.AddMenuItem("Page 2","mnuPage2")
Activity.AddMenuItem("Page 3","mnuPage3")
End Sub
Sub mnuPage1_Click
pnlPage2.Visible = False
pnlPage3.Visible = False
pnlPage1.Visible = True
End Sub
Sub mnuPage2_Click
pnlPage1.Visible = False
pnlPage3.Visible = False
pnlPage2.Visible = True
End Sub
Sub mnuPage3_Click
pnlPage1.Visible = False
pnlPage2.Visible = False
pnlPage3.Visible = True
End Sub
13 Example programs
226
13 Example programs
227
Sub Globals
Dim pnlPage1, pnlPage2, pnlPage3 As Panel
Dim pnlToolbox As Panel
End Sub
Send = Sender
pnlPage1.Visible=False
pnlPage2.Visible=False
pnlPage3.Visible=False
Select Send.Tag
Case "1"
pnlPage1.Visible=True
Case "2"
pnlPage2.Visible=True
Case "3"
pnlPage3.Visible=True
End Select
End Sub
'
'
'
'
'
'
'
'
'
'
'
228
We have:
- 3 pages, each one in its own Activity.
- 3 process global variables, Value1, Value2 and Value3
- on each page 1 EditText view to modify the Value variable with page index.
- 2 Labels to display the two other variables.
- on Page1 a small red square Panel to move around.
We can:
- Change Value1 in Page1.
- Change Value2 in Page2.
- Change Value3 in Page3.
- Move the small red square over the screen.
- Select either Page2 or Page3 on Page1.
229
230
Add now a new module "Page3" the same way as Page2 and modify the code like below:
'Activity module
Sub Process_Globals
End Sub
Sub Globals
Dim lblValue1_P3, lblValue2_P3 As Label
Dim edtValue3_P3 As EditText
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Page3")
' Loads "Page3" layout file
End Sub
Sub Activity_Resume
lblValue1_P3.Text = Main.Value1
lblValue2_P3.Text = Main.Value2
edtValue3_P3.Text = Main.Value3
End Sub
231
232
When the "Main" Activity is paused, due to either a page change or the program close, we:
- set variable Value1 to the edtValue1.Text content.
- save the Map to file Init.txt.
Sub Activity_Pause (UserClosed As Boolean)
Value1 = edtValue1_P1.Text
' get Value1 from edtValue1_P1.Text
File.WriteMap(File.DirInternal,"Init.txt",mapMoveTopLeft) ' Saves the Map
End Sub
To go back to Page1 from either Page2 or Page3, the user must press the Back key. To avoid that
the program stops when the user clicks, by inadvertence, one time too much, we check in Sub
Activity_KeyPress what key was pressed. And if it's the Back key we display a message in a
MessageBox asking the user if he really wants to quit the program. If Yes, then we set the Return
value to False that means that the event is sent back to the OS to close the program. If the answer is
No, we set the Return value to True, that means that we 'consume' the event and the OS will not
stop the program.
Sub Activity_KeyPress(KeyCode As Int) As Boolean
Dim Answ As Int
Dim Txt As String
If KeyCode = KeyCodes.KEYCODE_BACK Then' Checks if the KeyCode is BackKey
Txt = "Do you really want to quit the program ?"
Answ = Msgbox2(Txt,"A T T E N T I O N","Yes","","No",Null) ' MessageBox
If Answ = DialogResponse.POSITIVE Then
' If return value is Yes then
Return False
' Return = False the Event will not be consumed
Else
'
we leave the program
Return True
' Return = True
the Event will be consumed to avoid
End If
'
leaving the program
End If
End Sub
233
To show how to manage layout properties we have the small red square, pnlMove, that can be
moved on the screen. The position of pnlMove is handled in Sub Activity_Touch where we get
three parameters:
- Action
holding the value of the action the user made.
ACTION_DOWN
the user touches the screen.
ACTION_MOVE
the user moves on the screen
ACTION_UP
the user leaves the screen
- X
the X coordinate of the finger on the screen.
- Y
the Y coordinate of the finger on the screen.
To be able to move pnlMove we do the following:
- when Action is equal to ACTION_DOWN, the user touches the screen
we memorize the coordinates of the finger and the coordinates of the upper left corner of
pnlMove (lines 76 to 79).
-
when Action is equal to ACTION_MOVE the user moves his finger on the screen,
we calculate the relative displacement, dX and dY, in both directions and set the new Left
and Top properties of pnlMove (lines 82 to 85).
when Action is equal to ACTION_UP, the user leaves the screen and
we update the two properties in the Map object (lines 88 and 89=.
'
'
'
'
'
'
Case Activity.ACTION_MOVE
dX = X - X0
dY = Y - Y0
pnlMove.Left = X1 + dX
pnlMove.Top = Y1 + dY
'
'
'
'
'
Checks if ACTION_MOVE
Calculates the X distance moved
Calculates the X distance moved
Sets the new Left coordinate
Sets the new Top coordinate
Case Activity.ACTION_UP
' Checks if ACTION_UP
mapMoveTopLeft.Put("Left",pnlMove.Left) ' Memorizes Left in the Map
mapMoveTopLeft.Put("Top",pnlMove.Top)
' Memorizes Top in the Map
End Select
End Sub
234
In Sub btnPage_Click we start the Page Activity according to what button was pressed.
- We declare a new Button object, Send.
- We attribute Sender to Send .
Sender is the button view that raised the event.
- Depending on the Tag value of the sender object we start the correct Activity.
Sub btnPage_Click
Dim Send As Button
Send = Sender
Select Send.Tag
Case "2"
StartActivity("Page2")
Case "3"
StartActivity("Page3")
End Select
End Sub
Page 1:
We add the views like in the image at the left.
13.3
235
ScrollView examples
ScrollView is a very versatile view to display lists of objects holding data or user interface views.
ListViews are, currently, limited to two lines of text and an image per data set.
ScrollViews have an internal Panel, bigger than the screen, that can be scrolled vertically and holds
any type of views either as one layout or as lists of view sets.
Some screenshots of examples: ( a summary of ScrollView examples)
Gridline in TableView Scrollview
SQLLiteDB
Add imageview
ScrollView, layouts
HelpScrollView
236
237
Personally, I prefer working with variables rather than with values. The maintenance and
modification of a program is much easier with variables than with numerical values.
238
Sub Process_Globals
Dim StringUtils1 As StringUtils
Dim NumberOfColumns As Int
: NumberOfColumns = 5
Dim NumberOfRows As Int
Dim RowHeight As Int
: RowHeight = 30dip
Dim RowLineWidth As Int
: RowLineWidth = 1dip
Dim RowHeight_1 As Int
: RowHeight_1 = RowHeight - RowLineWidth
Dim ColLineWidth As Int
: ColLineWidth = 1dip
Dim ColumnWidth(NumberOfColumns) As Int
ColumnWidth(0) = 50dip
ColumnWidth(1) = 100dip
ColumnWidth(2) = 100dip
ColumnWidth(3) = 150dip
ColumnWidth(4) = 100dip
Dim ColumnWidth_1(NumberOfColumns) As Int
Dim TotalColumnWidth(NumberOfColumns + 1) As Int
Dim HeaderColor As Int
: HeaderColor = Colors.Blue
Dim HeaderFontColor As Int
: HeaderFontColor = Colors.Yellow
Dim HeaderLineColor As Int
: HeaderLineColor = Colors.Yellow
Dim LineColor As Int
: LineColor = Colors.Black
Dim CellColor As Int
: CellColor = Colors.RGB(255,255,220)
Dim FontColor As Int
: FontColor = Colors.Black
Dim FontSize As Float
: FontSize = 14
Dim Alignment As Int
: Alignment = Gravity.CENTER
Dim SelectedRow As Int
: SelectedRow = -1
Dim SelectedRowColor As Int
: SelectedRowColor=Colors.RGB(255,196,255)
Dim SelectedCellColor As Int
: SelectedCellColor=Colors.RGB(255,150,255)
Type RowCol (Row As Int, Col As Int)
Dim MoveLeft0, MoveX0, MoveX1, DeltaScroll, DeltaX As Float
Dim Time0 As Long
End Sub
239
240
Then we read the csv file, fill the headers and the table (ScrollView).
First, if the headers exist, we read the csv file with the headers.
Or, if the headers do not exist, we read the csv file without the headers and set the default
header names to Col1, Col2 etc.
Get the number of columns.
Display the headers SetHeader(h).
Display the table, by adding the different rows to the ScrollView AddRow(row).
Sub LoadTableFromCSV(Dir As String,Filename As String,HeadersExist As Boolean)
ClearAll 'Clears the previous table and loads the CSV file to the table
Dim List1 As List
Dim h() As String
If HeadersExist Then
' Reads the csv file
Dim headers As List
List1 = StringUtils1.LoadCSV2(Dir, Filename, ",", headers)
' Sets the header names of the columns
Dim h(headers.Size) As String
For i = 0 To headers.Size - 1
h(i) = headers.Get(i)
Next
Else
' Reads the csv file
List1 = StringUtils1.LoadCSV(Dir, Filename, ",")
' Sets default header names
Dim firstRow() As String
firstRow = List1.Get(0)
Dim h(firstRow.Length)
For i = 0 To firstRow.Length - 1
h(i) = "Col" & (i + 1)
Next
End If
NumberOfColumns = h.Length ' Gets the number of columns
SetHeader(h)
' Sets the headers
NumberOfRows = 0
For i = 0 To List1.Size - 1
' Fills the table
Dim row() As String
row = List1.Get(i)
AddRow(row)
Next
End Sub
241
242
Note: an underscore character at the end of a line means 'continue same instruction next line'.
243
Other functions:
Cell_Click
Click event of one of the cells in the table.
o Dim rc as a RowCol variable and Dim l as a Label
o Set l equal to the Sender, the View that raised the event
o Set rc equal to the Sender Tag parameter
o Call the SelectRow routine
o Display in the Activities title the row and column indexes and the cell content.
Sub Cell_Click
Dim rc As RowCol
Dim l As Label
l = Sender
rc = l.Tag
SelectRow(rc)
Activity.Title = "Cell: ("&rc.Row&", "& rc.Col&") "&GetCell(rc.Row, rc.Col)
End Sub
Header_Click
Click event of one of the header cells in the table.
o Dim l as a Label and Dim col as an integer
o Set I equal to the Sender
o Set col equal to the Sender Tag parameter, which is the column index.
o Display the selected column in the Activity title.
Sub Header_Click
Dim l As Label
Dim col As Int
l = Sender
col = l.Tag
Activity.Title = "Header clicked: " & col
End Sub
244
SelectRow
This routine manages the colors of the selected row and cell.
It is called from the Cell_Click routine
o Dim col as an integer.
o If there is a row selected, set the normal cell color.
o Set the SelectedRow variable to the new selected row index.
o Set the selected row and selected cell colors.
245
GetView
Gets the Label object for the given row and column.
o Dim l as a Label.
o Gets the View in the given row and column, the view index in the ScrollView panel
is equal to Row * NumberOfColumns + Col.
o Returns the Label.
GetCell
Gets the text of the Label for the given row and column.
o Gets the View in the given row and column.
o Return the Views Text parameter.
SetCell
(not used in the program)
Sets the text of the Label for the given row and column.
o Gets the View in the given row and column
o Sets the Views Text parameter to the given value
ClearAll
o Removes all Views (Labels) from the ScrollView Panel
o Sets the ScrollView Panel Height to 0
o Sets the selected row index to -1, no row selected
Sub ClearAll
'Clears the table
For i = scvPersons.Panel.NumberOfViews -1 To 0 Step -1
scvPersons.Panel.RemoveViewAt(i)
Next
scvPersons.Panel.Height = 0
SelectedRow = -1
End Sub
246
14 Basic language
247
14 Basic language
In computer programming, BASIC (an acronym which stands for Beginner's All-purpose Symbolic
Instruction Code) is a family of high-level programming languages designed to be easy to use.
The original Dartmouth BASIC was designed in 1964 by John George Kemeny and Thomas
Eugene Kurtz at Dartmouth College in New Hampshire, USA to provide computer access to nonscience students. At the time, nearly all use of computers required writing custom software, which
was something only scientists and mathematicians tended to do. The language and its variants
became widespread on microcomputers in the late 1970s and 1980s.
BASIC remains popular to this day in a handful of highly modified dialects and new languages
influenced by BASIC such as Microsoft Visual Basic. (source Wikipedia).
14.1
Program flow
This is a summary of the more detailed explanations in Process and Activity life cycle.
'Activity module
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
End Sub
Sub Activity_Create(FirstTime As Boolean)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
The program goes through following routines when starting from top to down:
14 Basic language
248
14 Basic language
249
5. Activity_Resume is called.
No code.
14 GPS
another event.
250
14 Basic language
251
14.2 Expressions
An expression in a programming language is a combination of explicit values, constants, variables,
operators, and functions that are interpreted according to the particular rules of precedence and of
association for a particular programming language, which computes and then produces (returns)
another value. This process, like for mathematical expressions, is called evaluation. The value can
be of various types, such as numerical, string, and logical (source Wikipedia).
For example, 2 + 3 is an arithmetic and programming expression which evaluates to 5. A variable is
an expression because it is a pointer to a value in memory, so y + 6 is an expression. An example of
a relational expression is 4 = 4 which evaluates to True (source Wikipedia).
Example
x + y
Addition
x - y
Subtraction
x * y
Multiplication
x / y
Division
Modulo
Power of
Mod
Power
x Mod y
Power(x,y) x
Precedence level: In an expression, operations with level 1 are evaluated before operations with
level 2, which are evaluated before operations with level 3.
Examples:
4 + 5 * 3 + 2 = 21
> 4 + 15 + 2
(4 + 5) * (3 + 2) = 45
> 9*5
(4 + 5)2 * (3 + 2) = 405
Power(4+5,2)*(3+2)
> 92 * 5
11 Mod 4 = 3
233
Power(23,3)
- 22 = - 4
(-2)2 = 4
> 81 * 5
14 Basic language
252
Operator
Example
Used to test
x=y
<>
x <> y
>
x>y
if the value of the left expression is greater than that of the right
<
x<y
if the value of the left expression is less than that of the right
>=
x >= y
if the value of the left expression is greater than or equal to that of the right
<=
x <= y
if the value of the left expression is less than or equal to that of the right
Comment
Boolean Or
Z = X Or Y
And
Boolean And
Not ( )
Boolean Not
And
False
False
False
False
True
False
True
False
False
True
True
False
True
True
True
True
14 Basic language
14.3
253
Conditional statements
If b = 0 Then a = 0
If b = 0 Then
a = 0
Else
a = 1
End If
If b = 0 Then a = 0 Else a = 1
14 Basic language
Note. Difference between:
B4A
Else If
254
VB
ElseIf
If b = 0 Then
a = 0
c = 1
End If
The semicolon character ' : ' in the line above is treated in B4A like a CarriageReturn CR character.
14 Basic language
255
Select TestExpression
Case ExpressionList1
' code1
Case ExpressionList2
' code2
Case Else
' code3
End Select
Examples:
Select Value
Case 1, 2, 3, 4
Select a + b
Case 12, 24
Select Txt.CharAt
Case "A", "B", "C"
14 Basic language
Note. Differences between:
B4A
Select Value
Case 1,2,3,4,8,9,10
256
VB
Select Case Value
Case 1 To 4 , 8 To 9
14 Basic language
14.4
257
Loop structures
i
n1
n2
n3
incremental variable
initial value
final value
step
Next
For i = 0 To 10 Step 1
is the same as
Next
Next
14 Basic language
Note : Differences between
B4A
Next
Exit
258
VB
Next i
Exit For
In VB :
The increment variable is added after the Next Keyword.
The loop type is specified after the Exit keyword.
n
Type
Array
Next
14 Basic language
259
14.4.3 Do - Loop
Several configurations exist:
Do While test
' code
Loop
Do Until test
' code
Loop
14 Basic language
260
Examples :
Do Until Loop :
Dim i, n As Int
i = 0
Do Until i = 10
' code
i = i + 1
Loop
Do While Loop :
Dim i, n As Int
i = 0
Do While i < 10
' code
i = i + 1
Loop
VB
Exit Loop
Do
' code
Loop Until test
14 Basic language
261
14.5 Subs
A Subroutine (Sub) is a piece of code. It can be any length, and it has a distinctive name
and a defined scope (in the means of variables scope discussed earlier). In Basci4Android code, a
subroutine is called Sub, and is equivalent to procedures, functions, methods and
subs in other programming languages. The lines of code inside a Sub are executed from
first to last, as described in the program flow chapter.
It is not recommended to have too long Subs, they get less readable.
14.5.1 Declaring
A Sub is declared in the following way:
Sub CalcInterest(Capital As Double, Rate As Double) As Double
Return Capital * Rate / 100
End Sub
It starts with the keyword Sub, followed by the Subs name, followed by a parameter list, followed
by the return type and ends with the keywords End Sub.
Subs are always declared at the top level of the module, you cannot nest two Subs
one inside the other.
Interest
CalcInterest
1235
5.25
instead of:
Interest = CalcInterest(1234, 5.2)
14 Basic language
262
14.5.4 Naming
Basically, you can name a Sub any name thats legal for a variable. It is recommended to
name the Sub with a significant name, like CalcInterest in the example, so you can tell what it
does from reading the code.
There is no limit on the number of Subs you can add to your program, but it is not
allowed to have two Subs with the same name in the same module.
Sub CalcInterest(Capital As Double, Rate As Double) As Double
Return Capital * Rate / 100
End Sub
14.5.5 Parameters
Parameters can be transmitted to the Sub. The list follows the sub name. The parameter list is put in
brackets.
The parameter types should be declared directly in the list.
Sub CalcInterest(Capital As Double, Rate As Double) As Double
Return Capital * Rate / 100
End Sub
14 Basic language
263
14.6 Events
In Object-oriented programming we have objects which can react on different user actions called
events.
The number and the type of events an object can raise depend on the type of the object.
User interface objects are called 'Views' in Android.
Summary of the events for different views :
Button
CheckBox
EditText
HorizontalScrollView
ImageView
Label
ListView
Panel
RadioButton
ScrollView
SeekBar
Spinner
TabHost
ToggleButton
WebView
PageFinished
OverrideUrl
TabChanged
ValueChanged
ScrollChanged
TextChanged
FocusChanged
EnterPressed
ItemLongClick
ItemClick
KeyUp
KeyPress
Up
Down
Touch
CheckedChange
Views
Activity
LongClick
Click
Events
14 Basic language
264
Click
Example:
Sub Button1_Click
' Your code
End Sub
LongClick
Example:
Event raised when the user clicks on the view and holds it pressed for a while.
Sub Button1_LongClick
' Your code
End Sub
14 Basic language
265
14 Basic language
14.7
266
Libraries
14 Basic language
267
If you setup a special additional libraries folder you must specify it in the IDE.
In the menu Tools / Configure Paths:
14 Basic language
268
14 Basic language
269
Result: 123;234;45;23
The different functions are:
CharAt(Index)
Returns the character at the given index.
CompareTo(Other)
Lexicographically compares the string with the Other string.
Contains(SearchFor)
Tests whether the string contains the given SearchFor string.
EndsWith(Suffix)
Returns True if the string ends with the given Suffix substring.
EqualsIgnoreCase(Other) Returns True if both strings are equal ignoring their case.
GetBytes(Charset)
Encodes the Charset string into a new array of bytes.
IndexOf(SearchFor)
Returns the index of the first occurrence of SearchFor in the
string.
IndexOf2(SearchFor, Index)
Returns the index of the first occurrence of SearchFor
in the string. Starts searching from the given index.
LastIndexOf(SearchFor) Returns the index of the first occurrence of SearchFor in the
string. Starts searching from the end of the string.
Length
Returns the length, number of characters, of the string.
Replace(Target, Replacement)
Returns a new string resulting from the replacement of
all the occurrences of Target with Replacement.
StartsWith(Prefix)
Returns True if this string starts with the given Prefix.
Substring(BeginIndex)
Returns a new string which is a substring of the original string.
The new string will include the character at BeginIndex and will extend to the end of the
string.
Substring2(BeginIndex,EndIndex)
Returns a new string which is a substring of the
original string. The new string will include the character at BeginIndex and will extend to
the character at EndIndex, not including the last character.
ToLowerCase
Returns a new string which is the result of lower casing this string.
ToUpperCase
Returns a new string which is the result of upper casing this string.
Trim
Returns a copy of the original string without any leading or trailing
white spaces.
Number formatting, display numbers as strings with different formats, there are two keywords:
NumberFormat(Number As Double, MinimumIntegers As Int, MaximumFractions As Int)
NumberFormat(12345.6789, 0, 2) = 12,345.68
NumberFormat(1, 3 ,0)
= 001
NumberFormat(Value, 3 ,0)
variables can be used.
NumberFormat(Value + 10, 3 ,0) arithmetic operations can be used.
NumberFormat((lblscore.Text + 10), 0, 0) if one variable is a string add parentheses.
14 Basic language
14.9
270
Timers
A Timer object generates ticks events at specified intervals. Using a timer is a good alternative to a
long loop, as it allows the UI thread to handle other events and messages.
Note that the timer events will not fire while the UI thread is busy running other code (unless you
call DoEvents keyword).
Timer events will not fire when the activity is paused, or if a blocking dialog (like Msgbox) is
visible.
It is also important to disable the timer when the activity is pausing and then enable it when it
resumes. This will save CPU and battery.
A timer has:
Three parameters.
o Initialize
Initializes the timer with two parameters, the EventName and the
interval.
Timer1.Initialize(EventName As String, Interval As Long)
Ex: Timer1.Initialize("Timer1", 1000)
o Interval
Sets the timer interval in milli-seconds.
Timer1. Interval = Interval
Ex: Timer1.Interval = 1000, 1 second
o Enabled
Enables or disables the timer. It is False by default.
Ex: Timer1.Enabled = True
One Event
o Tick
The Tick routine is called every time interval.
Ex: Sub Timer1_Tick
But it must be initialized in the Activity_Create routine in the module where the timer tick
event routine is used.
Sub Activity_Create(FirstTime As Boolean)
If FirstTime = True Then
Timer1.Initialize("Timer1", 1000)
End If
14 Basic language
271
14.10 Files
Many applications require access to a persistent storage. The two most common storage types are
files and databases.
14.10.1
File object
The predefined object File has a number of functions for working with files.
Files locations - There are several important locations where you can read or write files.
File.DirAssets
The assets folder includes the files that were added with the file manager in the IDE.
It's the Files folder in the project folder.
These files are read-only.
You can not create new files in this folder (which is actually located inside the apk file).
If you have a database file in the Dir.Assets folder you need to copy it to another folder before you
can use it.
File.DirInternal / File.DirInternalCache
These two folders are stored in the main memory of the device and are private to your application.
Other applications cannot access these files.
The cache folder may get deleted by the OS if it needs more space.
File.DirRootExternal
The storage card root folder.
File.DirDefaultExternal
The default folder for your application in the SD card.
The folder is: <storage card>/Android/data/<package>/files/
It will be created if required.
Note that calling any of the two above properties will add the EXTERNAL_STORAGE permission
to your application.
Tip: You can check if there is a storage card and whether it is available with
File.ExternalReadable and File.ExternalWritable.
To check if a file already exists use:
File.Exists ( Dir As String, FileName As String)
Returns True if the file exists and False if not.
The File object includes several methods for writing to files and reading from files.
To be able to write to a file or to read from a file, it must be opened.
14 Basic language
272
List1 = File.ListFiles(File.DirRootExternal)
14 Basic language
14.10.2
273
Filenames
14.10.3
Subfolders
To access the subfolder you should add the subfoldername to the foldername with "/" inbetween.
ImageView1.Bitmap = LoadBitmap(File.DirInternal & "/Pictures", "test1.png")
14 Basic language
14.10.4
274
TextWriter
There are two other useful functions for text files: TextWriter and TextReader:
TextWriter.Initialize (OutputStream As OutputStream)
- Initializes a TextWriter object as an output stream.
Example:
Dim Writer As TextWriter
Writer.Initialize(File.OpenOutput(File.DirRootExternal, "Test.txt" , False))
14 Basic language
14.10.5
275
TextReader
There are two other useful functions for text files: TextWriter and TextReader:
TextReader.Initialize (InputStream As InputStream)
- Initializes a TextReader as an input stream.
Example:
Dim Reader TextReader
Reader.Initialize(File.InputOutput(File.DirRootExternal, "Test.txt"))
TextReader
Reader.Initialize(File.OpenInput(File.DirRootExternal, "Test.txt"),"ISO-8859-1")
TextReader.ReadLine As String
- Reads the next line from the stream.
The new line characters are not returned.
Returns Null if there are no more characters to read.
Example:
Dim Reader As TextReader
Reader.Initialize(File.OpenInput(File.DirDefaultExternal, "Text.txt")
Dim line As String
line = Reader.ReadLine
Do While line <> Null
Log(line)
line = Reader.ReadLine
Loop
Reader.Close
TextReader.ReadList As List
- Reads the remaining text and returns a List object filled with the lines.
Closes the stream when done.
Example:
List1 = Reader.ReadList
14 Basic language
14.10.6
276
Text encoding
Text encoding or character encoding consists of a code that pairs each character from a given
repertoire with something else. Other terms like character set (charset), and sometimes character
map or code page are used almost interchangeably (source Wikipedia).
The default character set in Android is Unicode UTF-8.
In Windows the most common character sets are ASCII and ANSI.
ASCII includes definitions for 128 characters, 33 are non-printing control characters (now
mostly obsolete) that affect how text and space is processed.
ANSI, Windows-1252 or CP-1252 is a character encoding of the Latin alphabet, used by
default in the legacy components of Microsoft Windows in English and some other Western
languages with 256 definitions (one byte). The first 128 characters are the same as in the
ASCII encoding.
Many files generated by Windows programs are encoded with the ANSI character-set in western
countries. For example: Excel csv files, Notepad files by default.
But with Notepad, files can be saved with UTF-8 encoding.
Android can use following character sets:
UTF-8
default character-set
UTF -16
UTF - 16 BE
UTF - LE
US-ASCII
ASCII character set
ISO-8859-1
almost equivalent to the ANSI character-set
Windows-1251
cyrillic characters
Windows-1252
latin alphabet
To read Windows files encoded with ANSI you should use the Windows-1252 character-set.
If you need to write files for use with Windows you should also use the Windows-1252 characterset.
Another difference between Windows and Android is the end of line character:
Android, only the LF (Line Feed) character Chr(10) is added at the end of a line.
Windows, two characters CR (Carriage Return Chr(13)) and LF Chr(10) are added at the
end of a line. If you need to write files for Windows you must add CR yourself.
The symbol for the end of line is :
Basic4Android
CRLF
Basic4PPC
CRLF
Chr(10)
Chr(13) & Chr(10)
To read or write files with a different encoding you must use the TextReader or TextWriter objects
with the Initialize2 methods. Even for reading csv files.
14 Basic language
277
When you save a file with NotePad three additional bytes are added .
These bytes are called BOM characters (Byte Order Mark).
In UTF-8 they are represented by this byte sequence : 0xEF,0xBB,0xBF.
A text editor or web browser interpreting the text as Windows-1252 will display the characters
.
To avoid this you can use Notepad++ instead of NotePad and use Encode in UTF-8 without BOM.
Another possibility to change a text from Windows-1252 to UTF-8 is to use the code below.
Dim var, result As String
var = "Gesti"
Dim arrByte() As Byte
arrByte = var.GetBytes("Windows-1252")
result = BytesToString(arrByte, 0, arrByte.Length, "UTF8")
14 Basic language
278
14.11 Lists
Lists are similar to dynamic arrays, detailed descriptions of all functions are in chapter List.
Lists are often used and many examples can be found in code examples:
StringUtils
LoadCSV, SaveCSV
DBUtils module
InsertMaps, UpdateRecord, ExecuteMemoryTable, ExecuteSpinner,
ExecuteListView, ExecuteHtml, ExecuteJSON
Charts module
to hold different variables.
A list must be initialized before it can be used.
Initialize
Initializes an empty List.
Dim List1 As List
List1.Initialize
List1.AddAll(Array As Int(1, 2, 3, 4, 5))
Initialize2 (SomeArray)
Initializes a list with the given values. This method should be used to convert arrays to lists.
Note that if you pass a list to this method then both objects will share the same list, and if
you pass an array the list will be of a fixed size.
Meaning that you cannot later add or remove items.
Example 1:
Dim List1 As List
List1.Initialize2(Array As Int(1, 2, 3, 4, 5))
Example 2:
Dim List1 As List
Dim SomeArray(10) As String
' Fill the array
List1.Initialize2(SomeArray)
You can add and remove items from a list and it will change its size accordingly.
With either:
Add (item As Object)
Adds a value at the end of the list.
List1.Add(Value)
14 Basic language
279
A list can hold any type of object. However if a list is declared as a process global object it cannot
hold activity objects (like views).
Basic4android automatically converts regular arrays to lists. So when a List parameter is expected
you can pass an array instead.
Get the size of a List :
List1.Size
Use the Get method to get an item from the list with :
Get(Index As Int)
number = List1.Get(i)
You can use a For loop to iterate over all the values:
For i = 0 To List1.Size - 1
Dim number As Int
number = List1.Get(i)
...
Next
A List can be sorted (the items must all be numbers or strings) with :
Sort(Ascending As Boolean)
List1.Sort(True)
sort ascending
List1.Sort(False)
sort descending
SortCaseInsensitive(Ascending As Boolean)
Clear a List with :
List1.Clear
14 Basic language
280
14.12 Maps
A Map is a collection that holds pairs of keys and values, detailed descriptions of all functions are
in chapter Map.
The keys are unique. Which means that if you add a key/value pair (entry) and the collection
already holds an entry with the same key, the previous entry will be removed from the map.
The key should be a string or a number. The value can be any type of object.
Similar to a list, a map can hold any object, however if it is a process global variable then it cannot
hold activity objects (like views).
Maps are very useful for storing applications settings.
Maps are used in these example codes:
DBUtils module
used for database entries, keys are the column names and values the values.
StateManager module
used for settings
A list must be initialized before it can be used.
Initialize
Initializes an empty Map.
Dim Map1 As Map
Map1.Initialize
Get an entry :
Get(Key As Object)
Language = Map1.Get("Language")
Check if a Map contains en entry, tests whether there is an entry with the given key :
ContainsKey(Key As Object)
If Map1.ContainsKey("Language") Then
Msgbox("There is already an entry with this key !", "ATTENTION")
Return
End If
14 Basic language
281
Remove an entry :
Remove(Key As Object)
Map1.Remove("Language")
15 Graphics / Drawing
282
15 Graphics / Drawing
15.1 Overview
To draw graphics we need to use a Canvas object.
Explanations from the help file.
A Canvas is an object that draws on other views or (mutable) bitmaps.
When the canvas is initialized and set to draw on a view, a new mutable bitmap is created for that
view background, the current view's background is copied to the new bitmap and the canvas is set
to draw on the new bitmap.
The canvas drawings are not immediately updated on the screen. You should call the target view
Invalidate method to make it refresh the view.
This is useful as it allows you to make several drawings and only then refresh the display.
The canvas can be temporary limited to a specific region (and thus only affect this region). This is
done by calling ClipPath. Removing the clipping is done by calling RemoveClip.
You can get the bitmap that the canvas draws on with the Bitmap property.
This is an 'Activity Object', it cannot be declared under Sub Process_Globals.
It is possible to draw onto the following views:
Activity
ImageView
Panel
Bitmap (mutable)
In the following functions you will find a number of common parameters.
Bitmap1 as Bitmap
an Android bitmap
x, y. x1, y1, x2, y2 As Float
are coordinates, Float variables.
Color as Int
are color variables. Int variables
SrcRect, DestRact, Rect1 As Rect are rectangles, Rect objects
Filled As Boolean
flag if the surface is filled (True) or not (False)
The most common drawing functions are:
DrawBitmap (Bitmap1 As Bitmap, SrcRect As Rect, DestRect As Rect)
Draws the given bitmap or only a part of it..
SrcRect = source rectangle, can be only a part of the original bitmap.
DestRect = destination rectangle, can be any size.
Do draw with the same size both rectangles must have same width and same height.
If DestRect is different than SrcRect the destination drawing is stretched or shrinked
depending on the size ratios between the two rectangles.
15 Graphics / Drawing
283
15 Graphics / Drawing
284
15 Graphics / Drawing
15.2.1.1
285
Then we must load the layout file and initialize the two Canvases:
Sub Activity_Create(FirstTime As Boolean)
' load the layout file
Activity.LoadLayout("main")
' initialize the Canvas for the activity
cvsActivity.Initialize(Activity)
' initialize the Canvas for the pnlGraph panel
cvsGraph.Initialize(pnlGraph)
End Sub
15.2.1.2
Draw a line
Then we draw a horizonzal line onto pnlGraph with the same coordinates :
The coordinates are relative to the upper left corner of the view we draw on, the Panel pnlGraph in
this case.
' draw a horizontal line onto pnlGraph
cvsGraph.DrawLine(20dip, 20dip, 160dip, 20dip, Colors.Red, 3dip)
15 Graphics / Drawing
15.2.1.3
286
Draw a rectangle
Then we draw a filled rectangle onto pnlGraph with the same coordinates :
We don't need to define nor initialize a new rectangle because the coordinates are the same so we
use the same Rect object.
' draw a filled rectangle onto pnlGraph
cvsGraph.DrawRect(rect1, Colors.Blue, True, 3dip)
15 Graphics / Drawing
15.2.1.4
287
Draw a circle
Then we draw a filled circle with a border with a different color on the panel.
There is no direct function to draw a filled circle with a border with a different colors.
So we first draw the filled circle and then the circle border in two steps.
Instead of using fixed values like 220dip we can also use variables like in the code below.
When a same value is used several times it's better to use variables because if you need to change
the value you change it only once the value of the variable all the rest is changed automatically by
the variable.
' draw a filled circle with a boarder onto pnlGraph
Dim centerX, centerY, radius As Float
centerX = 220dip
centerY = 70dip
radius = 30dip
cvsGraph.DrawCircle(centerX, centerY, radius, Colors.Green, True, 3dip)
cvsGraph.DrawCircle(centerX, centerY, radius, Colors.Red, False, 3dip)
15 Graphics / Drawing
15.2.1.5
288
Draw a text
15 Graphics / Drawing
289
3 buttons
o
starts rotating
o
step by step moving
o
we can let turn either the needle
or the compass.
2 bitmap files
o compass.png
o needle.png
In the DrawBitmapRotated function the bitmap rotates around the bitmaps centre.
If we had a needle image like this one, we would need to do some calculations to make sure that
it turns around the needle centre.
To avoid these calculations, the needle bitmap looks like this one. We added the lower part so
that the needle centre is at the bitmap's centre.
The blue pixels are, in reality, transparent pixels.
15 Graphics / Drawing
290
: AngleStep = 6
: Angle = -AngleStep
: Mode = True
bmpCompass.Initialize(File.DirAssets,"compass.png")
bmpNeedle.Initialize(File.DirAssets,"needle.png")
15 Graphics / Drawing
291
imvCompass.Initialize("")
imvCompass.Bitmap = bmpCompass
imvNeedle.Initialize("")
imvNeedle.Color=Colors.Transparent
x = (100%x - bmpCompass.Width) / 2
y = (100%y - bmpCompass.Height) / 2
Activity.AddView(imvCompass, x, y, bmpCompass.Width, bmpCompass.Height)
Activity.AddView(imvNeedle, x, y, bmpCompass.Width, bmpCompass.Height)
csvCompass.Initialize(imvCompass)
RectCompass.Initialize(0, 0, bmpCompass.Width, bmpCompass.Height)
csvNeedle.Initialize(imvNeedle)
x = (bmpCompass.Width - bmpNeedle.Width)/2
y = (bmpCompass.Height - bmpNeedle.Height)/2
SRectNeedle.Initialize(0, 0, bmpNeedle.Width, bmpNeedle.Height)
DRectNeedle.Initialize(x, y, x + bmpNeedle.Width, y + bmpNeedle.Height)
Timer1.Initialize("Timer1",200)
Timer1_Tick
End Sub
15 Graphics / Drawing
292
15 Graphics / Drawing
293
We change the Mode variable from True to False or from False to True with the Not
keyword.
If Mode = True, rotating needle, we:
o Set the button text to "Needle turns".
o Draw a transparent rectangle to erase the current needle.
o Draw the needle at the new position.
o Draw the default compass.
If Mode = False, rotating compass, we:
o Set the button text to "Compass turns".
o Erase the current needle
o Draw the new needle.
15 Graphics / Drawing
294
You can play with the buttons to observe the different combinations of visible and hidden layers.
15 Graphics / Drawing
295
15 Graphics / Drawing
296
You can play with the buttons to show the different combinations of visible and hidden layers.
15 Graphics / Drawing
297
15 Graphics / Drawing
298
We have:
3 Panels
3 Canvases
3 ToggleButtons
1 Rect, rectangle used to draw rectangles
1 Bitmap, holding the activity's background image
1 BitmapDrawable, holds the activity's background
different variables used for the drawing.
Note that we use arrays of views for the three panels, canvases and togglebuttons.
Dim pnlLayer(3) As Panel instead of Dim pnlLayer0, pnlLayer1, pnlLayer2 As Panel.
In the Sub Activity_Create routine we initialize the different views and add them to the activity:
Sub Activity_Create(FirstTime As Boolean)
Dim i As Int
If FirstTime Then
bmpBackground.Initialize(File.DirAssets,"Rose2.jpg")
bdwBackground.Initialize(bmpBackground)
Activity.Background = bdwBackground
We:
15 Graphics / Drawing
299
btnLayer(i).Initialize("btnLayer")
x2 = x1 + i * 33%x
Activity.AddView(btnLayer(i), x2, y1, w, h)
btnLayer(i).TextOn = "Layer" & i & " ON"
btnLayer(i).TextOff = "Layer" & i & " OFF"
btnLayer(i).Checked = True
btnLayer(i).Tag = i
Next
End If
End Sub
In a loop we:
initialize the layer Panels.
we define an individual EventName for each of the three Panels
we use only an event on layout(0).
add the panels to the activity.
initialize the layer Canvases.
set the Panels Tag property to the index.
15 Graphics / Drawing
300
x1 = 10dip
y1 = 10dip
x2 = 150dip
y2 = 20dip
cvsLayer(2).DrawLine(x1,
y1 = 30dip
y2 = 30dip
cvsLayer(2).DrawLine(x1,
y1 = 35dip
y2 = 45dip
cvsLayer(2).DrawLine(x1,
y1 = 45dip
y2 = 55dip
cvsLayer(2).DrawLine(x1,
the last StrokeWidth parameter is '0', this means hairline mode, the width is one pixel.
cvsLayer(2).DrawLine(x1, y1, x2, y2, Colors.Green, 0.99dip)
here we use 0.99dip instead of 1dip because in some cases no line or only parts of it are
drawn. This is a known bug in Android with a StrokeWidth of '1'.
xc = 90dip
yc = 130dip
r1 = 70dip
cvsLayer(1).DrawCircle(xc, yc, r1, Colors.Green, False, 2dip)
r1 = 60dip
cvsLayer(0).DrawCircle(xc, yc, r1, Colors.Blue, True, 3dip)
r2 = 50dip
cvsLayer(0).DrawCircle(xc, yc, r2, Colors.Transparent, True, 1dip)
15 Graphics / Drawing
301
x1 = 200dip
y1 = 30dip
cvsLayer(2).DrawText("Rose", x1, y1, Typeface.DEFAULT,16,Colors.Red,"LEFT")
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
y1 = 50dip
cvsLayer(2).DrawText("Rose", x1, y1, Typeface.DEFAULT,16,Colors.Red,"CENTER")
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
y1 = 70dip
cvsLayer(2).DrawText("Rose", x1, y1, Typeface.DEFAULT,16,Colors.Red,"RIGHT")
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
draw the text "Rose" with the three different possible alignments.
draw the reference point for each text.
x1 = 260dip
y1 = 30dip
cvsLayer(2).DrawTextRotated("Rose", x1,y1,Typeface.DEFAULT,16,Colors.Red,"LEFT",-10)
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
y1 = 50dip
cvsLayer(2).DrawTextRotated("Rose", x1,y1,Typeface.DEFAULT,16,Colors.Red,"CENTER",-10)
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
y1 = 70dip
cvsLayer(2).DrawTextRotated("Rose", x1,y1,Typeface.DEFAULT,16,Colors.Red,"RIGHT",-10)
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
End Sub
18 Collections
302
Looking closer on the displayed texts we see the reference point for each text.
cvsLayer(2).DrawText("Rose", x1, y1, Typeface.DEFAULT,16,Colors.Red,"LEFT")
cvsLayer(2).DrawPoint(x1, y1, Colors.Red)
LEFT
alignment.
CENTER alignment.
RIGHT
alignment.
dim a local Button to get the view that raised the event.
set Send to the Sender view
change the Visible property from True to False or from False to True.
draw a dark gray circle to erase the previous blue and transparent circle.
set and yc to the new coordinates of the circle centers.
draw a blue and transparent circle on layer(1).
invalidate pnlLayout(1) to force the update of the drawing.
303
Select [value]
304
L1.Color = Colors.Red
L1.TextColor = Colors.Black
SubName(x, y)
Sub SubName()
Function FName()
As [var.type]
Exit Sub
Exit Function
General:
------DoEvents
while
in a Do Loop with DoEvents in it, WebView could not be
loaded
or if loaded, would not process a hyperlink click. And
Agraham
says: "Looping is bad practice on mobile devices. The CPU
will
be constantly executing code and using battery power as the
code will never get back to the OS idle loop where the
hardware
power saving measures are invoked."
Format()
InputBox($)
MsgBox "text"
i=MsgBox()
Int
MsgBox("text", "title")
MsgBox2(Message, Title, Positive, Cancel, Negative, Icon) as
--Rnd is < 1
305
Round(n)
i = Val(string)
If IsNumber(string) Then i = string Else i = 0 -An attempt to use i=string "throws an exception" if the
string is
not numbers.
control.SetFocus
view.RequestFocus
n / 0 : error
x = Shell("...")
TabIndex:
-------In VB6, TabIndex can be set to control the order in which controls get focus
when Tab is pressed. According to Erel, in B4A:
"Android handles the sequence according to their position. You can set
EditText.ForceDone = True in all your EditTexts. Then catch the
EditText_EnterPressed event and explicitly set the focus to the next
view (with EditText.RequestFocus)."
Setting Label Transparency:
-------------------------Properties - Back Style
Constants:
--------""
vbCr
vbCrLf
Quote = Chr$(34)
CRLF = Chr$(13)
none
String "Members":
---------------VB6 uses a character position pointer starting with 1.
B4A uses a character Index pointer starting with 0.
VB6
Mid$("abcde",
Mid$("abcde",
Mid$("abcde",
Mid$("abcde",
Mid$("abcde",
VB6
===
Mid$(text,
Mid$(text,
Mid$(text,
position]
Mid$(text,
1,
2,
3,
4,
5,
1)
1)
1)
1)
1)
=
=
=
=
=
"a"
"b"
"c"
"d"
"e"
=
=
=
=
=
letter
letter
letter
letter
letter
n, 1)
n)
n, x) [x=length wanted]
n, x) = text2
B4A
array
array
array
array
array
index
index
index
index
index
0 -- "a" = "abcde".CharAt(0)
1
2
3
4
B4A
===
text.CharAt(n-1)
text.SubString(n-1)
text.SubString2(n-1, n+x-1) [n+x-1=end
text = text.SubString2(0, n-2) & _
text2.SubString2(0, x-1) & _
text.SubString(n-1 + z) where...
z = Min(x, text2.length)
306
text.SubString2(0, n)
text.SubString(text.Length - n + 1)
If a.CompareTo(b)...
If text.EndsWith(text2)...
If text.StartsWith(text2)...
If text.EqualsIgnoreCase(text2)...
x = text.Length
text.Replace(str, str2)
text.ToLowerCase
text.ToUpperCase
text.Trim
If Lcase$(x) = Lcase$(y)...
text = Left$(text, n) & s &
Right$(Text, y)
Asc(s) [where s = a character]
text.IndexOf(string)
text.IndexOf2(string, int)
Returns -1 if not found.
Returns char. index, not position.
Starts search at "int".
If x.EqualsIgnoreCase(y)...
text.Insert(n, s)
same
Error Trapping:
-------------VB6:
===
Sub SomeSub
On [Local] Error GoTo ErrorTrap
...some code...
On Error GoTo 0 [optional end to error trapping]
...optional additional code...
Exit Sub [to avoid executing ErrorTrap code]
ErrorTrap:
...optional code for error correction...
Resume [optional: "Resume Next" or "Resume [line label]".
End Sub
B4A:
===
Sub SomeSub
Try
...some code...
Catch [only executes if error above]
Log(LastException) [optional]
...optional code for error correction...
End Try
...optional additional code...
End Sub
WIth B4A, if you get an error caught in the middle of a large subroutine, you
can
NOT make a correction and resume within the code you were executing. Only the
code
in "Catch" gets executed. That would seem to make Try-Catch-End Try of use
mainly
during development.
Try-Catch in place of GoTo:
-------------------------Try-Catch can be used as a substitute for GoTo [line label] for forward, but not
backward, jumps. It cannot be used to replace GoSub, for which B4A has no
equivalent.
Start the code with "Try" and replace the [line label] with "Catch".
307
Replace "GoTo [line label]" with code which will create an exception, which
causes
a jump to "Catch", such as OpenInput("bad path", "bad filename").
"Immediate Window" vs "Logs" Tab
-------------------------------Comments, variable values, etc., can be displayed in VB6's Immediate
Window by entering into the code "Debug.Print ...".
In the B4A environment, the Logs tab on the right side of the IDE is a
way to show the values of variables, etc., while the code is running.
Both VB6 and (now) B4A allow single-stepping through the code while it
is running and viewing the values of variables. VB6 also allows changing
the value of variables, changing the code, jumping to other lines from
the current line, etc. Because B4A runs on a PC while the app runs on
a separate device, B4A is currently unable to duplicate all of these
VB6 debug features.
17 FAQ
308
Beginner's Guide
17 FAQ
Some of the chapters below have been picked up from the forum.
At the bottom of this page there is a long list with all the
objects types.
17 FAQ
309
Beginner's Guide
o Initialize it and add it to the Activity (or a Panel) in the Activity_Create routine.
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
lblTitle.Initialize("")
Activity.AddView(lblTitle, 10dip, 10dip, 200dip, 50dip)
End If
List / Map.
List and Map objects must be Initialized before they can be used.
17 FAQ
310
Beginner's Guide
Becomes:
Answ = Msgbox2("Do you want to quit the program", _
"A T T E N T I O N", "Yes", "", "No", Null)
means split the line and put the rest on the next line.
ATTENTION :
The Home key cannot be trapped in the Activity_KeyPress event routine !
17 FAQ
311
Beginner's Guide
Examples:
Activity.AddMenuItem("Load", "mnuLoad")
Activity.AddMenuItem("Save", "mnuSave", image)
or
Activity.AddMenuItem("Load", "mnuLoad", LoadBitmap(File.DirAssets, "Load.png"))
Activity.AddMenuItem("Save", "mnuSave", LoadBitmap(File.DirAssets, "Save.png"))
17 FAQ
312
Beginner's Guide
17 FAQ
313
Beginner's Guide
17 FAQ
314
Beginner's Guide
Click on
and confirm to delete the files.
If you delete the files only in the folder, you will get a message for missing files the next
time you start the project.
You will be asked if you want to remove the files from the Files folder.
Oui > Yes
Non > No
Annuler > Cancel
o Yes
Removes the selected files from the Files folder, be sure that you have
backup files somewhere else if you need them afterwards.
o No
Removes the files from the project but leaves them in the Files folder.
o Cancel
Aborts the function.
17 FAQ
315
Beginner's Guide
Both
Portrait
Landscape
You can define screen orientations in the code with SetScreenOrientation from the Phone
library:
Landscape
Phone1.SetScreenOrientation(0)
Portrait
Phone1.SetScreenOrientation(1)
Both
Phone1.SetScreenOrientation(-1)
17 FAQ
316
Beginner's Guide
17 FAQ
317
Beginner's Guide
You need to specify the rank (number of dimensions) in the Sub definition with ',' .
If you want the Sub to return an array you must also speccify it.
Sub Test(a() As String, b(,) As String, c(,,) As String) As String
17 FAQ
318
Beginner's Guide
Needs the Reflection library (available only for users who bought Basic4Android) !
Examples:
17 FAQ
319
Beginner's Guide
17 FAQ
320
Beginner's Guide
17 FAQ
321
Pm As PackageManager
Inte As Intent
Packages As List
st As String
Packages = Pm.GetInstalledPackages
For i = 0 To Packages.size - 1
st=Packages.Get(i)
If st.Contains("calc") =True Then
Inte=Pm.GetApplicationIntent(st)
If Inte.IsInitialized Then
StartActivity(Inte)
Exit
End If
End If
Next
Beginner's Guide
17 FAQ
322
Beginner's Guide
In line Sub GetARGB(Color As Int) As Int() the () after Int are necessary because the return
value is an array.
17 FAQ
323
Beginner's Guide
17 FAQ
324
Beginner's Guide
TYPE_TEXT_FLAG_CAP_CHARACTERS
TYPE_TEXT_FLAG_CAP_SENTENCES
TYPE_TEXT_FLAG_CAP_WORDS
TYPE_TEXT_FLAG_NO_SUGGESTION
Sets to no suggestion.
EditText1.InputType = Bit.Or(EditText1.INPUT_TYPE_TEXT, 524288)
TYPE_TEXT_FLAG_AUTO_COMPLETE
Sets auto complete.
TYPE_TEXT_FLAG_AUTO_CORRECT
Sets auto correct.
TYPE_TEXT_VARIATION_EMAIL_ADDRESS
TYPE_TEXT_VARIATION_PASSWORD
17 FAQ
325
Beginner's Guide
TYPE_NUMBER_SIGNED
17 FAQ
326
Beginner's Guide
17.37 Get the dpi values of the device (dots per inch)
Needs the Reflection library.
Dim Xdpi,Ydpi As Float
Dim r As Reflector
r.Target = r.GetContext
r.Target = r.RunMethod("getResources")
r.Target = r.RunMethod("getDisplayMetrics")
Xdpi = r.GetField("xdpi")
Ydpi = r.GetField("ydpi")
17 FAQ
327
Beginner's Guide
18 Glossary
328
18 Glossary
Android Android is a software stack for mobile devices that includes an operating system,
middleware and key applications. Google Inc. purchased, in 2005, Android Inc. the company that
initially developed the software.
Java
Java is a programming language originally developed by James Gosling at Sun
Microsystems (which is now a subsidiary of Oracle Corporation) and released in 1995 as a core
component of Sun Microsystems' Java platform. The language derives much of its syntax from C
and C++ but has a simpler object model and fewer low-level facilities.
Activity An activity is a single, focused thing that the user can do. Almost all activities interact
with the user, so the Activity class takes care of creating a window for you in which you can place
your UI.
View
Provides classes that expose basic user interface classes that handle screen layout and
interaction with the user. Examples: Label, Panel, Button, EditText etc.