I needed some easy and multiplatform access to option choices. This small class, based on XUI Views (B4XDialog and B4XListTemplate) seems to work. You have to define a object like 'dlg' once and than you can ask the user for choices in just one line.
With ListMultiSelect2 you can define name, returnvalue and preselection for every item with the ';' separator. So you can return the items ID instead of the name. First idea was, to put the code in a code module, but this will not work with B4A, because of the resumable subs.
B4X:
Wait For (dlg.ListSelect(Array("Cat", "Dog", "Fish", "Crocodile"), "what you wanna eat?", 1)) Complete (Result As Int)
Log (Result)
B4X:
'Small Class to get List choices from a user, like the B4A integrated InputList
Sub Class_Globals
Private xui As XUI
Private base As B4XView
End Sub
'Initialize with Activity in B4A, Page1.RootPanel in B4i, MainForm.RootPane in B4J
Public Sub Initialize(pnl As B4XView)
base = pnl 'xui.CreatePanel("")
End Sub
'InputList for selecting one item
'if selected is > -1 then you can choose preselected item also with OK button
'returns selected index or -1 if no selection
Public Sub ListSelect(items As List, title As String, selected As Int) As ResumableSub
Dim options As B4XListTemplate
options.Initialize
options.Options = items
Dim dlg As B4XDialog
dlg.Initialize (base)
dlg.Title = title
'dlg.ButtonsYesToRight = True 'set Cancel-OK order only in future allowed ;-)
Dim sCancel As String = "Cancel"
Dim sOK As String = "OK"
If selected = -1 Then sOK = ""
Dim rs As ResumableSub = dlg.ShowTemplate(options, sOK, "", sCancel)
If selected > -1 Then options.CustomListView1.GetPanel(selected).Color = options.SelectionColor
Wait For (rs) Complete (Result As Int)
Dim iResult As Int
If Result = xui.DialogResponse_Positive Then
iResult = options.Options.IndexOf(options.SelectedItem)
If iResult = -1 Then iResult = selected
Else
iResult = -1
End If
Return iResult
End Sub
'Tries to use native or B4X built in controls
'B4A, B4J: built in InputList
'B4i: native ActionSheet, if no preselection and not too much items
'returns selected index or -1 if no selection
Public Sub ListSelect2(items As List, title As String, selected As Int) As ResumableSub
Dim iResult As Int = -4 'not handled
#if B4A
iResult = InputList(items, title, selected)
#Else If B4J
Dim fx As JFX
iResult = fx.InputList(Null, items, title, "", selected)
#Else If B4i
If selected = -1 And items.Size <= 100 Then
Dim sheet As ActionSheet
sheet.Initialize("sheet", title, "", "", items)
sheet.Show(base)
Wait For sheet_Click (value As String)
iResult = items.IndexOf(value)
End If
#end if
If iResult = -4 Then 'not handled yet with native controls
Wait For (ListSelect(items, title, selected)) Complete (result As Int)
iResult = result
End If
Return iResult
End Sub
'ListMultiselect for selecting more than one item
'returns a list with all selected items
Public Sub ListMultiSelect(items As List, title As String, selected As List) As ResumableSub
Dim options As B4XListTemplate
options.Initialize
options.Options = items
options.AllowMultiSelection = True '!
Dim dlg As B4XDialog
dlg.Initialize (base)
dlg.Title = title
'dlg.ButtonsYesToRight = True 'not possible yet, but this would be the right place to do it ;-)
Dim sCancel As String = "Cancel"
Dim sOK As String = "OK"
Dim rs As ResumableSub = dlg.ShowTemplate(options, sOK, "", sCancel)
If selected.IsInitialized Then options.SelectedItems.AddAll(selected) 'have to copy values, not reference like options.SelectedItems = selected
Wait For (rs) Complete (Result As Int)
If Result <> xui.DialogResponse_Positive Then Return Null
Return options.SelectedItems
End Sub
'ListMultiselect with a special format in itemsinfo: name;value;'True' if preselected
'usefull for uptating selected items via ID in database after user selection
'e.g. Array("Cat;1652;False", "Dog;7895;True", "Fish;2138;False", "Crocodile;7811;True")
'returns a list with the values of all selected items (or with iteminfos text, if not formated)
Public Sub ListMultiSelect2(itemsinfo As List, title As String) As ResumableSub
Dim liNames, liSelected As List, mapItems As Map
liNames.Initialize
liSelected.Initialize
mapItems.Initialize
For Each item As String In itemsinfo
Dim sCols() As String = Regex.Split(";", item)
If sCols.Length = 3 Then
mapItems.Put(sCols(0), sCols(1)) 'key is the name
liNames.Add(sCols(0))
If sCols(2) = "True" Then liSelected.Add(sCols(0))
Else
mapItems.Put(item, item)
End If
Next
Wait For (ListMultiSelect( liNames, title, liSelected)) Complete (result As List)
If result <> Null Then
Dim selectedValues As List
selectedValues.Initialize
For Each item As String In result
selectedValues.Add(mapItems.Get(item))
Next
End If
Return selectedValues
End Sub
Last edited: