Android search list while typing
I believe this is what you are looking for:
Have your Activity implement SearchView.OnQueryTextListener
and add the following methods:
public boolean onQueryTextChange(String newText) { if (TextUtils.isEmpty(newText)) { mListView.clearTextFilter(); } else { mListView.setFilterText(newText.toString()); } return true;}public boolean onQueryTextSubmit(String query) { return false;}
You can't do this with the search bar. But the listview has a possibility to filter on key pressed, like it is done in the contacts. The user simply starts typing and the list gets filtered then. Filtering is not really like searching. If you list contains the word foo somewhere and you type oo foo will be filtered out, but if you type fo it will stay even if the list item is call bar foo.
You simply have to enable it:
ListView lv = getListView();lv.setTextFilterEnabled(true);
I don't know how this is done if you don't have a hardware keyboard. I'm using the droid and starting to type starts the list to filter and to show only matching results.
I used an EditText
to do the job.
First I created two copies of the array to hold the list of data to search:
List<Map<String,String>> vehicleinfo;List<Map<String,String>> vehicleinfodisplay;
Once I've got my list data from somewhere, I copy it:
for(Map<String,String>map : vehicleinfo){ vehicleinfodisplay.add(map);}
and use a SimpleAdapter
to display the display (copied) version of my data:
String[] from={"vehicle","dateon","dateoff","reg"};int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg};listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to);vehiclelist.setAdapter(listadapter);
Then I added a TextWatcher
to the EditText
which responds to an afterTextChanged
event by clearing the display version of the list and then adding back only the items from the other list that meet the search criteria (in this case the "reg" field contains the search string). Once the display list is populated with the filtered list, I just call notifyDataSetChanged
on the list's SimpleAdapter
.
searchbox.addTextChangedListener(new TextWatcher(){ @Override public void afterTextChanged(Editable s) { vehicleinfodisplay.clear(); String search=s.toString(); for(Map<String,String>map : vehicleinfo) { if(map.get("reg").toLowerCase().contains(search.toLowerCase())) vehicleinfodisplay.add(map); listadapter.notifyDataSetChanged(); } }; ... other overridden methods can go here ...});
Hope this is helpful to someone.