Search in ListView

cjack3

Member
Hi everyone~

I'm currently borrowing my friend's machine (the license belongs to him) to create the app.

So, as the title indicates, I would like to know how to search in ListView. Basically, it would need to be able to search and filter the contents of a ListView depending on what you type in. I found a similar thread, where someone replied by saying this :


Sub EditTextSearch_TextChanged (Old As String, New As String)
If s.Len(s.Trim(New)) < 1 Then
ListViewSearch.Clear
Return
End If
holdp = pointer.Position
thm = pointer.RowCount - 1
Dim LVlbl As Label
LVlbl = ListViewSearch.SingleLineLayout.Label
LVlbl.Color = Colors.Gray
ListViewSearch.Clear
If RBnames.Checked Then
For l = 0 To thm
pointer.Position = l
seekvar = pointer.GetString ("name")
If s.At(s.Upper(seekvar), s.Upper(New)) > -1 Then
ListViewSearch.AddSingleLine(seekvar)
ListViewSearch.Invalidate
DoEvents
End If
Next
End If
If RBnotes.Checked Then
For l = 0 To thm
pointer.Position = l
seekvar = pointer.GetString ("enotesee")
If s.At(s.Upper(seekvar), s.Upper(New)) > -1 Then
ListViewSearch.AddSingleLine(pointer.GetString ("name"))
ListViewSearch.Invalidate
DoEvents
End If
Next
End If
pointer.Position = holdp
End Sub

(I couldn't understand what the reply meant, as I'm a beginner in Basic4Android programming).

Any help/advice/tips is appreciated, just be gentle to me, noob here :sign0104:

*Oh, also, could anyone tell me how to put the code in the proper format? Thanks*
 

Yafuhenk

Active Member
Licensed User
Longtime User
Why don't you use Autocompleteedittext

B4X:
Dim CustomerList As List
Dim adtCustomer As AutoCompleteEditText
Dim CustomerName As String
CustomerList.Initialize
For i = 1 To 100
   CustomerName = "Customer" & i
   CustomerList.Add(CustomerName)
Next
adtCustomer.SetItems(CustomerList)

Henk
 
Upvote 0

cjack3

Member
Hi Henk,

Thanks for replying! But I don't really catch how that would help me in implementing a search function in my app. Here's a brief overlook of how my app looks like :

zxvzb.png


As you can see, the listview is a vital portion of my application. When the user selects any one of the items in the listview, the relevant content will be displayed in the labels.

So, what I would like to implement in my application is a method to search the contents of the application. Or, a more proper word would be a method to 'filter' the listview.

If possible, I would like it to look something like this :

RMR1TVB6yaUAbmz-Sbu7wbfZss-CDT44CJX8Cw_VPEUXH13SZOiYgVoB_85h-aPkA0w


As the user enters text into the textbox, the contents of the listview will be filtered according to what is entered into the textbox.

Please advise on how to do this. Thanks in advance!
 
Upvote 0

HotShoe

Well-Known Member
Licensed User
Longtime User
Search

I use the routine below. It could easily be extended to use a find next button.

B4X:
Sub searchbtn_Click
   Dim count As Int
   Dim find As String
   
   For count = 0 To master.Size - 1
   tmp= master.GetItem(count) 'global string
   find = searchtxt.Text
   tmp1 = tmp.ToUpperCase ' global string
   
   If tmp1.IndexOf(find.ToUpperCase) > -1 Then Exit
   Next
   
   searchpan.Visible= False
   master.Top = 0
   
   master.SetSelection(count)
   
End Sub

--- Jem
 
Upvote 0

cjack3

Member
Hi,

I tried using Henk's method, but I got a strange error. It says that my 'Textbox' (the name that I used to declare my AutoCompleteEditText) is using the wrong type or something like that.

Erel : sorry, but I'm not exactly familiar with using databases in my applications.

HotShoe : I would probably sound like a total noob for saying this, but what do I have to declare to use your code? When I used it, there was a lot of undeclared variables.

Thanks for your help, everyone!
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
I have a similar issue. What I wish to accomplish is to have a searchbox, into which the user types words and the listbox gets filtered as they type. Using code found on the forums I've made the following, which doesn't work:
Can someone help me? [I'm using the Designer for the layouts]
Thanks

B4X:
Sub Activity_Create(FirstTime As Boolean)

   
   Dim StationCount As Int
   Dim i As Int
  
   
   'If FirstTime AND SQL1.IsInitialized = False Then 
      Dim dir As String
      dir = CopyDBFromAssets("lineinfo.db")
      SQL1.Initialize(dir,"lineinfo.db",True)
   'End If   
   
   Activity.LoadLayout("StationFreeSearch")   
   StationList.SingleLineLayout.Label.TextColor = Colors.Black
   
   StationCount = SQL1.ExecQuerySingleResult("SELECT count(DISTINCT StationName) FROM lineinfo")
   For i = 1 To StationCount
      StationList.AddSingleLine(SQL1.ExecQuerySingleResult("SELECT DISTINCT StationName FROM lineinfo WHERE StationAlphaID = " & i ))
   Next 
      

  Searchbox.SetItems(Array As String("Baker Street","Charing Cross","etc."))
  Searchbox.InputType = Searchbox.INPUT_TYPE_TEXT
   
End Sub
Sub Searchbox_TextChanged (Old As String, New As String)
   
   Dim Searchbox As AutoCompleteEditText 
   Dim StationList As ListView
  
   'Searchbox.Initialize("")
   Dim Cursor1 As Cursor

   StationList.Initialize("")
   Cursor1 = SQL1.ExecQuery("SELECT DISTINCT StationName FROM lineinfo WHERE stationname LIKE '%" &New & "%'")

   StationList.Clear
   For i = 0 To Cursor1.RowCount - 1
      Cursor1.Position = i
      StationList.AddSingleLine(Cursor1.GetString("StationName")) 'not sure this needs to be StationName (thats the column name Im looking for...)
   Next
'   Searchbox.SetItems(StationList)
   Cursor1.Close

End Sub
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
You do you Dim and initialize StationList? You should use the same ListView you created with the designer.

Hi,

It's Dim-d in that Activity's globals. Not initialised though because it's from the Designer so it's just a LoadLayout.
The problem that's not working is the searchbox: what I'd like is when users type in stuff, the list would re-list itself (ie not just the searchbox would offer the possiblities from the text list which here ends in 'etc' but also the list to change).
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
The code you posted doesn't reference any global ListView.

Here's the begninning of the Activity.
B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim SQL1 As SQL
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.
   
   Dim Searchbox As AutoCompleteEditText 
   Dim StationList As ListView
End Sub
Sub CopyDBFromAssets (FileName As String) As String
   Dim TargetDir As String
   If File.ExternalWritable Then TargetDir = File.DirDefaultExternal Else TargetDir = File.DirInternal
   'If File.Exists(TargetDir, FileName) = False Then
         File.Copy(File.DirAssets, FileName, TargetDir, FileName)
   'End If
   Return TargetDir
End Sub
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
Can you post your complete code?

For the Activity or the whole whole thing? (the activity is really just these two half posts you already saw, there isn't more to it)
If the whole thing you need, can I email it or PM it?
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
I don't understand why you call Dim StationList inside the sub. This will cause this variable to reference a new uninitialized ListView.

I'm not at home now (where the app is) but as far as I remember if I don't dim it in there, it gets unhappy about the list being uninitialised. I'll check in the evening.

(pretty much my background is more VBA than VB so there are quite a few gaps in my knowledge as to how things work here and there...)
 
Upvote 0

Bas Hamstra

Member
Licensed User
Longtime User
Delete and rebuild the ListView

I am assuming a Button here, to confirm the EditText input, but it doesn't really matter. The below code can rebuild the ListView extremely fast, even if the ListView loads thousands of hits. In fact I used it on a 2 million word dictionary with no restrictions and it can display all words containing an '"e" (which is zillions) in few seconds. To restrict the hits to say 1000 (then simply cutoff) or so would make response nearly instant.

Bas

Sub Button1_Click
Dim Word As String
Dim Pat As String
ListView1.Clear
Pat = EditText1.Text

DoEvents

For n=0 To List1.Size-1
Word = List1.Get(n)
if Word.Contains(Pat) Then ListView1.AddSingleLine(Word)
Next

End Sub
 
Upvote 0

nemethv

Member
Licensed User
Longtime User
I am assuming a Button here, to confirm the EditText input, but it doesn't really matter. The below code can rebuild the ListView extremely fast, even if the ListView loads thousands of hits. In fact I used it on a 2 million word dictionary with no restrictions and it can display all words containing an '"e" (which is zillions) in few seconds. To restrict the hits to say 1000 (then simply cutoff) or so would make response nearly instant.

Bas

Sub Button1_Click
Dim Word As String
Dim Pat As String
ListView1.Clear
Pat = EditText1.Text

DoEvents

For n=0 To List1.Size-1
Word = List1.Get(n)
if Word.Contains(Pat) Then ListView1.AddSingleLine(Word)
Next

End Sub

Sorry pls bear w me as I'm a bit new to some of this.
EditText1 is the searchbox (?)
ListView is my StationList I guess?
What's List1? I don't think I have the equivalent of that one. I think I have a ListView, but not a List as such.
thnx.
 
Upvote 0
Top