ListView Filter is correct, but shows an incorrect result

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:

  • S ho e
  • T ho t

However, the list I get is the first two elements:

  • Bell
  • Pictogram

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; } } 
+4
source share
1 answer

It seems to me that your problem most likely lies in the getView(..) method of your adapter.

This line, in particular -

 Helmet helmet = getItem (position); 

If you return an element in the original helmet array, this explains why you get the results. However, I cannot be sure, because I do not see your getItem(..) method hosted in your code. If this is true, then of course you would like to return the filtered results here (if any), and not from the unfiltered list.

+5
source

Source: https://habr.com/ru/post/1212355/


All Articles