Note that there are some explanatory texts on larger screens.

plurals
  1. POCustom filtering in Android using ArrayAdapter
    text
    copied!<p>I'm trying to filter my ListView which is populated with this ArrayAdapter:</p> <pre><code>package me.alxandr.android.mymir.adapters; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import me.alxandr.android.mymir.R; import me.alxandr.android.mymir.model.Manga; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Filter; import android.widget.SectionIndexer; import android.widget.TextView; public class MangaListAdapter extends ArrayAdapter&lt;Manga&gt; implements SectionIndexer { public ArrayList&lt;Manga&gt; items; public ArrayList&lt;Manga&gt; filtered; private Context context; private HashMap&lt;String, Integer&gt; alphaIndexer; private String[] sections = new String[0]; private Filter filter; private boolean enableSections; public MangaListAdapter(Context context, int textViewResourceId, ArrayList&lt;Manga&gt; items, boolean enableSections) { super(context, textViewResourceId, items); this.filtered = items; this.items = filtered; this.context = context; this.filter = new MangaNameFilter(); this.enableSections = enableSections; if(enableSections) { alphaIndexer = new HashMap&lt;String, Integer&gt;(); for(int i = items.size() - 1; i &gt;= 0; i--) { Manga element = items.get(i); String firstChar = element.getName().substring(0, 1).toUpperCase(); if(firstChar.charAt(0) &gt; 'Z' || firstChar.charAt(0) &lt; 'A') firstChar = "@"; alphaIndexer.put(firstChar, i); } Set&lt;String&gt; keys = alphaIndexer.keySet(); Iterator&lt;String&gt; it = keys.iterator(); ArrayList&lt;String&gt; keyList = new ArrayList&lt;String&gt;(); while(it.hasNext()) keyList.add(it.next()); Collections.sort(keyList); sections = new String[keyList.size()]; keyList.toArray(sections); } } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(v == null) { LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.mangarow, null); } Manga o = items.get(position); if(o != null) { TextView tt = (TextView) v.findViewById(R.id.MangaRow_MangaName); TextView bt = (TextView) v.findViewById(R.id.MangaRow_MangaExtra); if(tt != null) tt.setText(o.getName()); if(bt != null) bt.setText(o.getLastUpdated() + " - " + o.getLatestChapter()); if(enableSections &amp;&amp; getSectionForPosition(position) != getSectionForPosition(position + 1)) { TextView h = (TextView) v.findViewById(R.id.MangaRow_Header); h.setText(sections[getSectionForPosition(position)]); h.setVisibility(View.VISIBLE); } else { TextView h = (TextView) v.findViewById(R.id.MangaRow_Header); h.setVisibility(View.GONE); } } return v; } @Override public void notifyDataSetInvalidated() { if(enableSections) { for (int i = items.size() - 1; i &gt;= 0; i--) { Manga element = items.get(i); String firstChar = element.getName().substring(0, 1).toUpperCase(); if(firstChar.charAt(0) &gt; 'Z' || firstChar.charAt(0) &lt; 'A') firstChar = "@"; alphaIndexer.put(firstChar, i); } Set&lt;String&gt; keys = alphaIndexer.keySet(); Iterator&lt;String&gt; it = keys.iterator(); ArrayList&lt;String&gt; keyList = new ArrayList&lt;String&gt;(); while (it.hasNext()) { keyList.add(it.next()); } Collections.sort(keyList); sections = new String[keyList.size()]; keyList.toArray(sections); super.notifyDataSetInvalidated(); } } public int getPositionForSection(int section) { if(!enableSections) return 0; String letter = sections[section]; return alphaIndexer.get(letter); } public int getSectionForPosition(int position) { if(!enableSections) return 0; int prevIndex = 0; for(int i = 0; i &lt; sections.length; i++) { if(getPositionForSection(i) &gt; position &amp;&amp; prevIndex &lt;= position) { prevIndex = i; break; } prevIndex = i; } return prevIndex; } public Object[] getSections() { return sections; } @Override public Filter getFilter() { if(filter == null) filter = new MangaNameFilter(); return filter; } private class MangaNameFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { // NOTE: this function is *always* called from a background thread, and // not the UI thread. constraint = constraint.toString().toLowerCase(); FilterResults result = new FilterResults(); if(constraint != null &amp;&amp; constraint.toString().length() &gt; 0) { ArrayList&lt;Manga&gt; filt = new ArrayList&lt;Manga&gt;(); ArrayList&lt;Manga&gt; lItems = new ArrayList&lt;Manga&gt;(); synchronized (items) { Collections.copy(lItems, items); } for(int i = 0, l = lItems.size(); i &lt; l; i++) { Manga m = lItems.get(i); if(m.getName().toLowerCase().contains(constraint)) filt.add(m); } result.count = filt.size(); result.values = filt; } else { synchronized(items) { result.values = items; result.count = items.size(); } } return result; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { // NOTE: this function is *always* called from the UI thread. filtered = (ArrayList&lt;Manga&gt;)results.values; notifyDataSetChanged(); } } } </code></pre> <p>However, when I call filter('test') on the filter nothing happens at all (or the background-thread is run, but the list isn't filtered as far as the user conserns). How can I fix this?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload