B4A Library [Class] SearchView - More powerful alternative to AutoCompleteEditText

Status
Not open for further replies.
Edit: better to use B4XDialog + B4XSearchTemplate

SearchView is made of an EditText and ListView. When the user enters text into the EditText the ListView shows the items that start with this text or that contain the text (in this order).

This view is useful for allowing the user to select an item from many items.

Advantages over AutoCompleteEditText:
  • SearchView uses an internal index that is built when you call SetItems. This allows it to quickly find the matches.
  • SearchView also shows items that contain the input text (not just prefixes).
  • The class code can be further customized as needed.

upload_2017-2-21_17-48-19.png


Tutorial about handling large, searchable lists: https://www.b4x.com/android/forum/t...e-list-with-searchview-b4xserializator.61872/
 

Attachments

  • SearchView.zip
    45.1 KB · Views: 2,356
Last edited:

tcgoh

Active Member
Licensed User
Longtime User
Your code looks correct (assuming that you only use it to test this functionality). Which error do you get?
Hi Erel,

Yes, I only use it to test the code.
No, I didn't get any error message in the Log, But I also did not get any search display on the "SV" when text was enter.

Here's my full code
B4X:
Sub Process_Globals
    Dim index As Object
    Dim newObj As Object
End Sub

Sub Globals
    Dim sv As SearchView
    Dim Panel1 As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    sv.Initialize(Me, "sv")
    sv.AddToParent(Panel1, 0, 0, Panel1.Width, Panel1.Height)
  
    Dim raf As RandomAccessFile
    raf.Initialize(File.DirRootExternal, "test.txt", False)
    raf.WriteObject(index, True, 0)
    newObj = raf.ReadObject(0)
    raf.Close
    Return newObj
  
    sv.SetIndex(newObj)
End Sub
 

tcgoh

Active Member
Licensed User
Longtime User
Sorry can you show me how to build the index from the "test.txt" file and then saving it.
Tks
 

Mahares

Expert
Licensed User
Longtime User
By storing the index in a file and retrieving it from the file, what happened if you add new items to your list. I am guessing they will not be indexed , hence do not show up when searched for. Could you please confirm or refute my assumption.
 

aldomoscarda

Member
Licensed User
Longtime User
I love SearchView but may help to use in BD. This is my incomplete code:

Sub Activity_Create(FirstTime As Boolean)
'Do not forget to load the layout file created with the visual designer. For example:
'Activity.LoadLayout("cuarto")
Activity.Color = Colors.white
sv.Initialize(Me, "sv")
Label1.Initialize("label1")
sv.AddToParent(Activity, 0, 0, 200dip, 300dip)

If FirstTime Then
'******************************************************************************************
If File.Exists(File.DirInternal, "DATOS.db") = True Then
If SQL1.IsInitialized = False Then
SQL1.Initialize(File.DirInternal, "DATOS.db",True )
End If
Dim Cursor As Cursor
Cursor = SQL1.ExecQuery("SELECT * FROM PRODUCTOS WHERE PRD_NOMBRE LIKE'" & Label1.Text.Trim.ToUpperCase & "%' Group BY PRD_NOMBRE")
End If
'******************************************************************************************
Else
' sv.SetIndex(index)
End If

End Sub
Sub sv_ItemClick(Value As String)
Msgbox("Chosen value: " & Value, "")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

Tomas Petrus

Active Member
Licensed User
Longtime User
Hi,

Is there any way how to use this SearchView with more than 100 rows in text file? Replace ListView with something else?

Thanks for replay
 

jinxaw

Member
Licensed User
Longtime User
Hi,

what code do i have to add, in order to use the Searchview in combination with the Designer? Could someone help me please?
Thank you very much!

Best regards,
Daniel
 

merlin2049er

Well-Known Member
Licensed User
Longtime User
Can I add this view via the designer? I tried using a custom view and setting it to a search view. Not sure about the custom property?

Thanks,
Joe
 

arnold steger

Member
Licensed User
Longtime User
When click a button then open a listview and at top is the edittext from sv
when click the button then stopped the programm.
not find my problem, need help

B4X:
Sub NamenButton_Click
NamenList.Initialize
    Namen.Initialize("Namen")
    For i = 1 To Namen_ListeGross.Size-1
    Dim PointsTempG() As String = Regex.Split(",",Namen_ListeGross.Get(i))
    Namen.AddSingleLine(PointsTempG(2)&","&PointsTempG(0)&","&PointsTempG(1)&",")
    NamenList.Add(PointsTempG(2))
    Next
    For i = 1 To Namen_ListeKlein.Size-1
    Dim PointsTempK() As String = Regex.Split(",",Namen_ListeKlein.Get(i))
    Namen.AddSingleLine(PointsTempK(2)&","&PointsTempK(0)&","&PointsTempK(1)&",")
    NamenList.Add(PointsTempK(2))
    Next
 
    Activity.AddView(Namen, 0, 50dip, 100%x, 100%y-100dip)
    ToastMessageShow(Namen.Size & " Flurnamen gefunden", True)
 
    svN.Initialize(Me, "svN")
    svN.AddToParent(Activity, 0, 0, 200dip, 300dip)
    index=svN.SetItems(NamenList)
'    svN.SetIndex(index,NamenList)
End Sub

Error occurred on line: 53 (searchview)
java.lang.RuntimeException: Object should first be initialized (ListView).

at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:49)
at anywheresoftware.b4a.objects.ListViewWrapper.Clear(ListViewWrapper.java:197)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
at anywheresoftware.b4a.objects.EditTextWrapper$1.afterTextChanged(EditTextWrapper.java:83)
at android.widget.TextView.sendAfterTextChanged(TextView.java:7626)
at android.widget.TextView.setText(TextView.java:3859)
at android.widget.TextView.setText(TextView.java:3708)
at android.widget.EditText.setText(EditText.java:81)
at android.widget.TextView.setText(TextView.java:3683)
at android.widget.TextView.setTransformationMethod(TextView.java:1755)
at android.widget.TextView.applySingleLine(TextView.java:7307)
at android.widget.TextView.setInputType(TextView.java:4075)
at anywheresoftware.b4a.objects.EditTextWrapper.setInputType(EditTextWrapper.java:174)
at com.Flurnamenkarte.Gemeinde.Kiens.searchview._initialize(searchview.java:85)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:305)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
at com.maximus.quickpopup.quickpopup$1.onItemClick(quickpopup.java:85)
at com.maximus.quickpopup.quickpopup$3.onClick(quickpopup.java:161)
at android.view.View.performClick(View.java:4463)
at android.view.View$PerformClick.run(View.java:18789)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
at dalvik.system.NativeStart.main(Native Method)
 

Lee Gillie CCP

Active Member
Licensed User
Longtime User
This is wonderful. I am adapting a bit for my purposes. I have a list of class of products, with part #, description, price, etc. I am intending to use two searchviews for invoice line item detail input page. One searchview on a product # input for the line item, and another searchview on description input for the line item. So the user can searchview on EITHER product # or description on the line item detail edit page. The searchview list displayed to the user in both cases will show BOTH part # and description, but essentially they are picking a product class record. There are about 1,000 items in my products list. I believe I can see how to customize SearchView to fit the design above.

As I was studying the code, though, there is a MAP called noDuplicates. I was curious why a Map was used for this instead of a List? Is the key searching for a Map faster than using IndexOf on a List? I could see no purpose for the map item value. It is always set to an empty string. And seems like the List might be more resource efficient? Perhaps IndexOf doesn't work the way I picture it in my mind. Perhaps the Map key search is quicker?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Is the key searching for a Map faster than using IndexOf on a List?
Yes. It is much faster and it is doesn't require more resources. List.IndexOf needs to go over all the items to see whether there is a duplicate or not.

With a Map it is more or less a single check based on the hashcode.
 
Status
Not open for further replies.
Top