I have a custom Adapter that I use to display custom objects in a ListView . In addition, I used SearchView , which allows me to search for ListView results and filter the results. However, I noticed some strange behavior when I try to enter a search. While I am looking for an item that is in the list, the item will be displayed in the filter, however the items are always displayed at the top of the list. If there are 10 elements in the list and the search produces 5 matches, then the result displays the first 5 elements in the list instead of 5 actual matches. For example, consider this list with 6 motorcycle helmets on it:
- Bell
- Pictogram
- Harley davidson
- Joe rocket
- Shoei
- Thor
If I search for "ho", the resulting list should look like this:
However, the list I get is the first two elements:
I cannot understand why the search is not working properly. Any help would be greatly appreciated. My code is shown below ...
HelmetActivity.java
public class HelmetActivity extends ActionBarActivity implements SearchView.OnQueryTextListener{ private Menu menu; private ListView listView; private HelmetAdapter helmetAdapter; private List<Helmet> arrayList; private SearchManager searchManager; private SearchView searchView; private MenuItem searchMenuItem; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.helmet_activity); ActionBar actionBar = getSupportActionBar(); actionBar.setElevation(0); listView = (ListView) findViewById(R.id.helmet_listview); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); arrayList = new ArrayList<Helmet>(); listView.setLongClickable(true); helmetAdapter = new HelmetAdapter(this, R.layout.helmet, arrayList); listView.setAdapter(helmetAdapter); arrayList.add(new Helmet("Bell")); arrayList.add(new Helmet("Icon")); arrayList.add(new Helmet("Harley Davidson")); arrayList.add(new Helmet("Joe Rocket")); arrayList.add(new Helmet("Shoei")); arrayList.add(new Helmet("Thor")); } @Override public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.helmet_activity_menu, menu); SearchManager searchManager = (SearchManager) getSystemService( Context.SEARCH_SERVICE); searchMenuItem = menu.findItem(R.id.action_search); searchView = (SearchView) searchMenuItem.getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo( getComponentName())); searchView.setSubmitButtonEnabled(true); searchView.setOnQueryTextListener(HelmetActivity.this); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { helmetAdapter.getFilter().filter(newText); return true; } }
HelmetAdapter.java
public class HelmetAdapter extends ArrayAdapter<Helmet> implements Filterable { private int resource; private LayoutInflater inflater; private Context context; private List<Helmet> helmetList; private List<Helmet> filteredHelmetList; private HelmetFilter helmetFilter; public HelmetAdapter (Context pContext, int pResource, List<Helmet> helmetList) { super (pContext, pResource, helmetList); resource = pResource; inflater = LayoutInflater.from (pContext); context = pContext; this.helmetList = helmetList; this.filteredHelmetList = helmetList; getFilter(); } @Override public View getView (final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(resource, parent, false); } String uri; int imageResource; Drawable image; Helmet helmet = getItem (position); TextView hName = (TextView) convertView.findViewById(R.id.h_name); hName.setText(helmet.getName()); return convertView; } @Override public int getCount() { return filteredHelmetList.size(); } @Override public Filter getFilter() { if (helmetFilter == null) { helmetFilter = new HelmetFilter(); } return helmetFilter; } private class HelmetFilter extends Filter { @Override protected FilterResults performFiltering (CharSequence constraint) { FilterResults filterResults = new FilterResults(); if (constraint != null && constraint.length() > 0) { ArrayList<Helmet> temporaryHelmetList = new ArrayList<Helmet>(); for (Helmet helmet : helmetList) { if (helmet.getName().toLowerCase().contains(constraint.toString() .toLowerCase())) { temporaryHelmetList.add(helmet); } } filterResults.count = temporaryHelmetList.size(); filterResults.values = temporaryHelmetList; } else { filterResults.count = helmetList.size(); filterResults.values = helmetList; } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { filteredHelmetList = (ArrayList<Helmet>) results.values; notifyDataSetChanged(); } } }
Helmet.java
public class Helmet { public Helmet (String name) { super(); this.name = name; } private String name; public String getName () { return name; } public void setName (String pName) { this.name = pName; } }
source share