B4A Library Another Multi-Select-"Spinner"

It wraps this Github project. Posting the B4A project, the B4A library files, and the Java Code. There are a number of folders and files in the B4A project's /Objects/res folder. You will need them to be in any project that you create with this B4A project (not - all, but I leave it up to you to make sense of the files in the values and drawable folders and how to modify/use/adjust them).

For each view there are two events that will be raised:
1. selected - It is raised when you click on OK. In this event you can get a Boolean array of items selected in the list
2. cancelled - It is raised when you click on Cancel. In this event you can also get a Boolean array of items that are selected in the list. Just do the same call to for eg ms1.Selected as in the example code below/attached.

1.png


2.png


3.png


Some sample code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: MultiSpinner
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False

#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

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.

    Private ms1, ms2 As MultiSpinner

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("main")
   
   
    ms1.SpinnerData = Array As String("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
    ms1.ShowTheSpinner
    ms1.Selected = Array As Boolean(True, False, True, False, True, False, True)
   
   ms2.SpinnerData = Array As String("Mercedes Benz", "BMW", "Nissan", "Toyota", "Hyundai", "Mitsubishi")
'  if commented out then by default all will be unselected
'  ms2.Selected = Array As Boolean(True, False, True, False, True, False) 
   ms2.ShowToastMessage = False   
   ms2.ShowTheSpinner
 
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ms1_selected
   
    Dim selectitems() As Boolean
    selectitems = ms1.Selected
    For i = 0 To selectitems.Length - 1
        Log("ms1 item " & i  & " = " & selectitems(i))
    Next
    Log (" ")
   
End Sub

Sub ms2_selected
   
    Dim selectitems() As Boolean
    selectitems = ms2.Selected
    For i = 0 To selectitems.Length - 1
        Log("ms2 item " & i  & " = " & selectitems(i))
    Next
    Log(" ")
   
End Sub

Sub ms1_cancelled
   
    Log("ms1 Cancel clicked")
    Log(" ")

End Sub

Sub ms2_cancelled
   
    Log("ms2 Cancel clicked")
    Log(" ")

End Sub

MultiSpinner
Author:
Johan Schoeman
Version: 1
  • MultiSpinner
    Fields:
    • ba As BA
    Methods:
    • BringToFront
    • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
    • Initialize (EventName As String)
    • Invalidate
    • Invalidate2 (arg0 As Rect)
    • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • IsInitialized As Boolean
    • RemoveView
    • RequestFocus As Boolean
    • SendToBack
    • SetBackgroundImage (arg0 As Bitmap)
    • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
    • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
    • SetTextColorAnimated (arg0 As Int, arg1 As Int)
    • SetTextSizeAnimated (arg0 As Int, arg1 As Float)
    • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
    • ShowTheSpinner
    Properties:
    • Background As Drawable
    • Color As Int [write only]
    • Enabled As Boolean
    • Gravity As Int
    • Height As Int
    • Left As Int
    • Selected()() As Boolean
    • ShowToastMessage As Boolean [write only]
    • SpinnerData() As String [write only]
    • Tag As Object
    • Text As String
    • TextColor As Int
    • TextSize As Float
    • Top As Int
    • Typeface As Typeface
    • Visible As Boolean
    • Width As Int
 

Attachments

  • TheJavaCode.zip
    111.2 KB · Views: 396
  • b4aMultiSpinnerLibFiles.zip
    11.2 KB · Views: 534
  • b4aMultiSpinner.zip
    117.5 KB · Views: 530

Johan Schoeman

Expert
Licensed User
Longtime User
Hi Johan,

how do I get the toast into a variable?

greeting
I will have to amend the wrapper. But it can be done. You want to pass your own string to be displayed when OK is clicked?
 

Johan Schoeman

Expert
Licensed User
Longtime User
I need the items selected in a variable so that I can write to a table
I will do some changes so that the selected items will be returned in an array. Will post it when done. Give a day or two to do so.
 

Johan Schoeman

Expert
Licensed User
Longtime User
I need the items selected in a variable so that I can write to a table
You can actually do it without me having to change anything. Take for eg

ms1.SpinnerData = Array As String("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")

and change it to

Dim mydays() as String = Array As String(("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
ms1.SpinnerData = mydays

Then in Sub ms1_selected you can use the boolean values that were returned in selectitems(i) to extract the selected names of the selected items in array mydays() by checking True and False. If for eg selectitems(0) = true then mydays(0) should be one of the variables you need for your table.

It should be straight forward to do....;)
 

RauchG

Active Member
Licensed User
Longtime User
At the moment I feel the array so (Tip of Don Manfred)

B4X:
Sub SpinnerPromoart
  
    Dim dbCursor As Cursor

    SQL1.Initialize(File.DirDefaultExternal, "baustein.db3", True)    'ignore

    dbCursor = SQL1.ExecQuery("SELECT * FROM drp_promotionarten")
    Dim mPromoartString(dbCursor.RowCount) As String
  
    For i = 0 To dbCursor.RowCount - 1        'dbCursor.RowCount = 5
        dbCursor.Position = i
        mPromoartString(i) = dbCursor.GetString("NAME")
    Next
  
'    ms1.SpinnerData = Array As String("SP PET EW", "SP Dosen/Display", "SP Suprema Glas", "Perrier PET EW", "SP Festlich gedeckter Tisch")
    ms1.SpinnerData = mPromoartString
  
    dbCursor.Close
      
End Sub
 

DaveW

Active Member
Licensed User
Longtime User
Hi Johan,

I am trying to use the Multi-Spinner but something odd is happening in the Visual Designer. When I add the MultiSpinner from Custom View to my layout, the Properties contains 5 Custom Properties. But if I look at the MultiSpinners in your example app, or even add a MultiSpinner to your app, there are no Custom Properties. The properties are "Boolean Example", "Int Example", "String with List", "String Example" and "Color Example".

Also, when I try to compile my app with the Multi-Spinner, I get an error "Object reference not set to an instance of an object." when I try to set the SpinnerData property.

Do you have any idea what is happening and how I can fix this?
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hi Johan,

.....the Properties contains 5 Custom Properties. But if I look at the MultiSpinners in your example app, or even add a MultiSpinner to your app, there are no Custom Properties. The properties are "Boolean Example", "Int Example", "String with List", "String Example" and "Color Example".

I have no idea where this comes from - it is not in my library and also not in my B4A sample project...


Also, when I try to compile my app with the Multi-Spinner, I get an error "Object reference not set to an instance of an object." when I try to set the SpinnerData property.
Do you have any idea what is happening and how I can fix this?


The declaration is in Sub Globals and the order of msX.Selected is important i.e it should be only after msX.ShowTheSpinner

B4X:
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Private ms1, ms2, ms3 As MultiSpinner
End Sub
.....
.....
.....

ms3.SpinnerData = Array As String("Apple", "Orange", "Banana", "Pear", "Grape", "Guava")
'  if commented out then by default all will be unselected
ms3.ShowToastMessage = False   
ms3.ShowTheSpinner 
ms3.Selected = Array As Boolean(True, False, True, False, True, False)

Note that the labels serve no purpose other than to indicate where the applicable Multispinner is "hiding" in the display. Thus, clicking in the area of the label will result in the spinner becoming visible
 

DaveW

Active Member
Licensed User
Longtime User
Hi Johan, thank you for the quick reply. I was afraid it might be nothing to do with your code! I think it must be getting confused with some other similar view used elsewhere in my app. At least I know now to look internally.
I am using the code straight out of your example in my app so the sequence is correct. I think the error is probably a knock-on from the custom properties problem.
 

vbmundo

Well-Known Member
Licensed User
Hi,

This Lib is a great control.

I have an error when the Spinner have only 1 value.

Look

B4X:
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
MySQL Database not connected!
Sub NOT FOUND: 'vertablas_status
Connected to Database
** Activity (main) Pause, UserClosed = false **
** Activity (listatablas) Create, isFirst = true **
** Activity (listatablas) Resume **
** Activity (listatablas) Pause, UserClosed = false **
** Activity (estructuras) Create, isFirst = true **
** Activity (estructuras) Resume **
** Activity (estructuras) Pause, UserClosed = false **
** Activity (addfield) Create, isFirst = true **
** Activity (addfield) Resume **
** Activity (addfield) Pause, UserClosed = true **
** Activity (estructuras) Resume **
ReConnecting
Sub NOT FOUND: 'vertablas_status
Auto-Reconnect Attempt #1 of 15
Sub NOT FOUND: 'vertablas_status
Database connection re-established
Sub NOT FOUND: 'vertablas_status
~w:1002,table20,1900549
** Activity (estructuras) Pause, UserClosed = true **
** Activity (listatablas) Resume **
ReConnecting
Sub NOT FOUND: 'vertablas_status
Auto-Reconnect Attempt #1 of 15
Sub NOT FOUND: 'vertablas_status
Database connection re-established
Sub NOT FOUND: 'vertablas_status
** Activity (listatablas) Pause, UserClosed = false **
** Activity (estructuras) Create, isFirst = false **
** Activity (estructuras) Resume **
** Activity (estructuras) Pause, UserClosed = false **
** Activity (indices) Create, isFirst = true **
Sub NOT FOUND: 'tablas_status
Connected to Database
Error occurred on line: 207 (INDICES)
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
    at multiselectwrapper.multiSelectWrapper.ShowTheSpinner(multiSelectWrapper.java:184)
    at b4a.example.indices._cargocampos(indices.java:419)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:702)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
    at b4a.example.indices.afterFirstLayout(indices.java:102)
    at b4a.example.indices.access$000(indices.java:17)
    at b4a.example.indices$WaitForLayout.run(indices.java:80)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4947)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (indices) Resume **
** Activity (main) Resume **
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hi,

This Lib is a great control.

I have an error when the Spinner have only 1 value.

Look

B4X:
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
MySQL Database not connected!
Sub NOT FOUND: 'vertablas_status
Connected to Database
** Activity (main) Pause, UserClosed = false **
** Activity (listatablas) Create, isFirst = true **
** Activity (listatablas) Resume **
** Activity (listatablas) Pause, UserClosed = false **
** Activity (estructuras) Create, isFirst = true **
** Activity (estructuras) Resume **
** Activity (estructuras) Pause, UserClosed = false **
** Activity (addfield) Create, isFirst = true **
** Activity (addfield) Resume **
** Activity (addfield) Pause, UserClosed = true **
** Activity (estructuras) Resume **
ReConnecting
Sub NOT FOUND: 'vertablas_status
Auto-Reconnect Attempt #1 of 15
Sub NOT FOUND: 'vertablas_status
Database connection re-established
Sub NOT FOUND: 'vertablas_status
~w:1002,table20,1900549
** Activity (estructuras) Pause, UserClosed = true **
** Activity (listatablas) Resume **
ReConnecting
Sub NOT FOUND: 'vertablas_status
Auto-Reconnect Attempt #1 of 15
Sub NOT FOUND: 'vertablas_status
Database connection re-established
Sub NOT FOUND: 'vertablas_status
** Activity (listatablas) Pause, UserClosed = false **
** Activity (estructuras) Create, isFirst = false **
** Activity (estructuras) Resume **
** Activity (estructuras) Pause, UserClosed = false **
** Activity (indices) Create, isFirst = true **
Sub NOT FOUND: 'tablas_status
Connected to Database
Error occurred on line: 207 (INDICES)
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
    at multiselectwrapper.multiSelectWrapper.ShowTheSpinner(multiSelectWrapper.java:184)
    at b4a.example.indices._cargocampos(indices.java:419)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:702)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
    at b4a.example.indices.afterFirstLayout(indices.java:102)
    at b4a.example.indices.access$000(indices.java:17)
    at b4a.example.indices$WaitForLayout.run(indices.java:80)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4947)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (indices) Resume **
** Activity (main) Resume **

The attached library files should sort it out.
 

Attachments

  • MultiSpinnerLibFilesV1_01.zip
    11.4 KB · Views: 308

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I would like to modify your code to take / use Lists instead of Arrays and before I try just wanted to make sure this isn't something you have already done
 

Johan Schoeman

Expert
Licensed User
Longtime User
I would like to modify your code to take / use Lists instead of Arrays and before I try just wanted to make sure this isn't something you have already done
You are more than welcome to change the code.
 
Top