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:

incendio

Well-Known Member
Licensed User
Longtime User
Dear Erel,

I have tried this class with about 18500 records, crashed during built an index.
I built my self almost similar function to searchview, not a class, since my skill is not enough.

Function built using sqlite data(in internal sdcard) and its index feature. Very-very fast, 18500 records shows almost instantly, though only capable to search first letters only (ab->display all data start with ab, etc).
 

Mahares

Expert
Licensed User
Longtime User
@incendio: Can you zip and post your project so we can see how you can achieve that speed. Who knows, perhaps someone can help you change it where you can search by a string anywhere in the column, not just the start. SQLite has that capability.
 

LucaMs

Expert
Licensed User
Longtime User
Dear Erel,

I have tried this class with about 18500 records, crashed during built an index.
I built my self almost similar function to searchview, not a class, since my skill is not enough.

Function built using sqlite data(in internal sdcard) and its index feature. Very-very fast, 18500 records shows almost instantly, though only capable to search first letters only (ab->display all data start with ab, etc).


You could try my ComboSearch.
It saves the data in a SQLite database (indexed).
But it has two fields: the first contains the words to search, the second an object that will be returned along with the word; this object can also be null.
You can fill the list from a db, but it does not have a progressbar.
I did a test with 18500 records: a long time to load, only a moment to look for.
 

LucaMs

Expert
Licensed User
Longtime User
Uhm...

You probably do not have the necessity of the second field.

But the main problem is the duplication of data: to fill the internal db you must also put the db containing the data in the project.

This feature that I added seems to be useless :D
 

incendio

Well-Known Member
Licensed User
Longtime User
@incendio: Can you zip and post your project so we can see how you can achieve that speed. Who knows, perhaps someone can help you change it where you can search by a string anywhere in the column, not just the start. SQLite has that capability.
Yes, I can search anywhere in the column, but don't need it, so, not included in my function.

I have tested to include search anywhere in the column, speed is slower than only search first letters, but still very fast and acceptable. For a small data, I think, won't be any different.

Function is very simple but the sample data is large, +/- 2.5MB, so I stripped down sample data in order to post here.
 

Attachments

  • LV.zip
    14.9 KB · Views: 348

LucaMs

Expert
Licensed User
Longtime User
You only have the ability to find words that start with a certain letter capitalized.

With this line:
DB.ExecNonQuery ("PRAGMA case_sensitive_like = OFF") [or ON]

you can solve at least the upper/lower case.
 

incendio

Well-Known Member
Licensed User
Longtime User
You only have the ability to find words that start with a certain letter capitalized.

With this line:
DB.ExecNonQuery ("PRAGMA case_sensitive_like = OFF") [or ON]

you can solve at least the upper/lower case.
Thanks for the tip, but I need my data to be capitalized.
 

Mahares

Expert
Licensed User
Longtime User
@incendio: Your project only has 96 records. That does not make for a good test. Having all 18500 records would have made for a good test. For your info, edt.text would still work. You did not have to change it to edt.text.ToUppercase in your select statement. Also , sometimes when you are running a query, the fewer columns requested in the SQL statement, the faster the query runs. In your case SELECT nm is faster than SELECT nm,id because you did not need the id.
 

incendio

Well-Known Member
Licensed User
Longtime User
Yes, it is only 96 records, cause this is just a sample, to big to post the whole records to this forum.

The sample project is just to give an idea how to deal with large data and i have tested with 18500 records.
 

hzchrisfang

Member
Licensed User
Longtime User
Hello Erel,
How would I add the searchview to a customdialog? I have a try, but the itemclick event not work.
 

Shay

Well-Known Member
Licensed User
Longtime User
Hi
Strange thing, the "ProgressDialog"
is not shown in nexsus 4
is it ok on galaxy s2, s3..
any idea why? / how do I overcome this?
 

Shay

Well-Known Member
Licensed User
Longtime User
you mean add more on this line? (change 100 to 200?)
If i Mod100 = 0ThenDoEvents
 

tcgoh

Active Member
Licensed User
Longtime User
Moving the code to a service will not help. Services code run in the same thread as any other code.

If the data is static then you can store the index in a file and then load it instead of building it.

Hi,

How do you store the index into a file?
Sorry I'm new on searchiew and I have a large txt file which takes a long time building it upon starting the APP.

Thanks
 

tcgoh

Active Member
Licensed User
Longtime User
Sorry I'm not familiar with RandomAccessfile. I use this code but its not working
B4X:
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)

Thanks for helping
 
Status
Not open for further replies.
Top