Android Code Snippet [B4X] [XUI] easy and fast list choices

skrjabin

Active Member
Licensed User
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.
B4X:
Wait For (dlg.ListSelect(Array("Cat", "Dog", "Fish", "Crocodile"), "what you wanna eat?", 1)) Complete (Result As Int)
   Log (Result)
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:
'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:

skrjabin

Active Member
Licensed User
This variant tries to use native or built in controls if possible. If not it uses the Sub ListSelect.
B4X:
'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
 
Last edited:

skrjabin

Active Member
Licensed User
This is possible with the latest version of XUI Views.
Wow, thank you, this is really needed for me!
If I got it correctly, we can set with version 1.88 of XUI Views the ButtonsOrder. The default is left orientated OK-button
B4X:
Array As Int(xui.DialogResponse_Positive, xui.DialogResponse_Negative, xui.DialogResponse_Cancel)
And we can customize it like
B4X:
Dialog.ButtonsOrder = Array As Int(XUI.DialogResponse_Negative, XUI.DialogResponse_Cancel, XUI.DialogResponse_Positive)
Great!
 
Top