listview - Custom filtering in Android using ArrayAdapter -
i'm trying filter listview populated arrayadapter:
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<manga> implements sectionindexer { public arraylist<manga> items; public arraylist<manga> filtered; private context context; private hashmap<string, integer> alphaindexer; private string[] sections = new string[0]; private filter filter; private boolean enablesections; public mangalistadapter(context context, int textviewresourceid, arraylist<manga> 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<string, integer>(); for(int = items.size() - 1; >= 0; i--) { manga element = items.get(i); string firstchar = element.getname().substring(0, 1).touppercase(); if(firstchar.charat(0) > 'z' || firstchar.charat(0) < 'a') firstchar = "@"; alphaindexer.put(firstchar, i); } set<string> keys = alphaindexer.keyset(); iterator<string> = keys.iterator(); arraylist<string> keylist = new arraylist<string>(); 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 && 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) { (int = items.size() - 1; >= 0; i--) { manga element = items.get(i); string firstchar = element.getname().substring(0, 1).touppercase(); if(firstchar.charat(0) > 'z' || firstchar.charat(0) < 'a') firstchar = "@"; alphaindexer.put(firstchar, i); } set<string> keys = alphaindexer.keyset(); iterator<string> = keys.iterator(); arraylist<string> keylist = new arraylist<string>(); 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 = 0; < sections.length; i++) { if(getpositionforsection(i) > position && previndex <= 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: function *always* called background thread, , // not ui thread. constraint = constraint.tostring().tolowercase(); filterresults result = new filterresults(); if(constraint != null && constraint.tostring().length() > 0) { arraylist<manga> filt = new arraylist<manga>(); arraylist<manga> litems = new arraylist<manga>(); synchronized (items) { collections.copy(litems, items); } for(int = 0, l = litems.size(); < 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: function *always* called ui thread. filtered = (arraylist<manga>)results.values; notifydatasetchanged(); } } }
however, when call filter('test') on filter nothing happens @ (or background-thread run, list isn't filtered far user conserns). how can fix this?
this fixed problem. i'm not it's best solution, works. project's open-source, feel free use of code here should prove usefull :-).
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<manga> implements sectionindexer { public arraylist<manga> items; public arraylist<manga> filtered; private context context; private hashmap<string, integer> alphaindexer; private string[] sections = new string[0]; private filter filter; private boolean enablesections; public manga getbyposition(int position) { return items.get(position); } public mangalistadapter(context context, int textviewresourceid, arraylist<manga> items, boolean enablesections) { super(context, textviewresourceid, items); this.filtered = items; this.items = arraylist<manga> items.clone(); this.context = context; this.filter = new manganamefilter(); this.enablesections = enablesections; if(enablesections) { alphaindexer = new hashmap<string, integer>(); for(int = items.size() - 1; >= 0; i--) { manga element = items.get(i); string firstchar = element.getname().substring(0, 1).touppercase(); if(firstchar.charat(0) > 'z' || firstchar.charat(0) < 'a') firstchar = "@"; alphaindexer.put(firstchar, i); } set<string> keys = alphaindexer.keyset(); iterator<string> = keys.iterator(); arraylist<string> keylist = new arraylist<string>(); 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 = filtered.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 && 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) { (int = items.size() - 1; >= 0; i--) { manga element = items.get(i); string firstchar = element.getname().substring(0, 1).touppercase(); if(firstchar.charat(0) > 'z' || firstchar.charat(0) < 'a') firstchar = "@"; alphaindexer.put(firstchar, i); } set<string> keys = alphaindexer.keyset(); iterator<string> = keys.iterator(); arraylist<string> keylist = new arraylist<string>(); 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 = 0; < sections.length; i++) { if(getpositionforsection(i) > position && previndex <= 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: function *always* called background thread, , // not ui thread. constraint = constraint.tostring().tolowercase(); filterresults result = new filterresults(); if(constraint != null && constraint.tostring().length() > 0) { arraylist<manga> filt = new arraylist<manga>(); arraylist<manga> litems = new arraylist<manga>(); synchronized (this) { litems.addall(items); } for(int = 0, l = litems.size(); < 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(this) { result.values = items; result.count = items.size(); } } return result; } @suppresswarnings("unchecked") @override protected void publishresults(charsequence constraint, filterresults results) { // note: function *always* called ui thread. filtered = (arraylist<manga>)results.values; notifydatasetchanged(); clear(); for(int = 0, l = filtered.size(); < l; i++) add(filtered.get(i)); notifydatasetinvalidated(); } } }
Comments
Post a Comment