Android listview custom filter and filterable interface

  • 4,196 views
Uploaded on

Tutorial on using android listview with a custom filter. It helps to filter a listview while user inserts key in the text box. It uses android filterable interface. You can download the code at …

Tutorial on using android listview with a custom filter. It helps to filter a listview while user inserts key in the text box. It uses android filterable interface. You can download the code at github.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
4,196
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
36
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Android developer blog. Tutorial for android development that helps you to become an android developerAndroid developer blog. Tutorial for android development that helps you to become an android developer Surviving W/ AndroidSurviving W/ Android byJFrankie, Android ListView : Custom Filter And Filterable Interface October 18, 2012 5 Like 1 In the previous post we showed the way we can programming a custom adapter and a custom layout. One aspect we didn’t cover by now, is how we can filter the items in the ListView. In this post we describe how we can filter items inside a ListView while the user writes words inside an input field. We can use the example shown in the last post and modify it. What do we need to do it? Modify the custom adapter, PlanetAdapter so that it will be able to filter the items Add an input field where the user can insert the keys to filter the ListView Let’s start then. If we didn’t use a custom adapter with custom object inside the ListView, the things would be much easier. For example if we used just String as item content we simply could add a few lines of code to make our list filterable; but we have a custom layout that uses not a simply String but a complex object (i.e. Planet). So we need first modify our custom adapter (PlanetAdapter) so that it implements the android.widget.Filter interface. This interface requires we implement just only one method called getFilter() that returns a android.widget.Filter object. The problem is the way we can create this filter. Very easy! We create a private class called PlanetFilter that extends the android.widget.Filter. This class has two abstract methods: FilterResults performFiltering(CharSequence constraint) : invoked in worker thread, that has the task to filter the results according to the constraint void publishResults(CharSequence constraint,FilterResults results): that has the task to show the result set created by performingFiltering method Let’s suppose we want to filter the planet list using the name attribute. In our case, then, the constraint can be the initial letters of the planet name, so that if the planet starts with those letters we show it otherwise we hide it. MODIFY THE CUSTOMADAPTER SO THAT IT IMPLEMENTS THE FILTERABLE INTERFACE 1 2 3 4 5 6 7 8 9 10 11 12 private class PlanetFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { .... } @Override protected void publishResults(CharSequence constraint,FilterResults results) { ..... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); // We implement here the filter logic if (constraint == null || constraint.length() == 0) { // No filter implemented we return all the list results.values = planetList; results.count = planetList.size(); } else { // We perform filtering operation List<Planet> nPlanetList = new ArrayList<Planet>(); for (Planet p : planetList) { if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase())) nPlanetList.add(p); Follow SwA 123 MyApponGoogle Play Android app development :weather app with forecast Android Detect Face Android HTTP Client : Network error and ConnectivityManager Android UML : Design an App – Part 2 Android UML: Design an App – Part 1 Recent Posts Widget by Helplogger Recent Posts Android ListView– Tutorial and basic example Android ListView: Custom Adapter and Layout Android ListView: Custom Filter and Filterable interface Add a sliding menu with animation to an Activity Android HTTP Client: GET, POST, Download, Upload, Multipart Request Popular Posts ? ? converted by Web2PDFConvert.com
  • 2. In this method we have to return a FilterResults that has two static attributes called values and count. Values is a list of values to be shown while count is the number of these values. The first thing we do in this method is to verify if the constraint is null or empty, in this case we don’t have to filter the result and simply In other words all the list. If the constraints aren’t null or empty we simply select the planet with its name starting with the constraint, as shown below. The next step is publishing the result. We said before that the PlanetAdapter has to implement Filterable interface and it has to implement getFilter() method: This is code is quite trivial, we simply invalidate the result set if the result list is empty or we notify that the result set is changed. It is done!….quite done!…We need now adding just an input field where user can insert the keyword to filter the result. The new layout becomes: 17 18 19 20 21 22 23 24 } results.values = nPlanetList; results.count = nPlanetList.size(); } return results; } 1 2 results.values = planetList; results.count = planetList.size(); 1 2 3 4 5 6 7 8 9 List<Planet> nPlanetList = new ArrayList<Planet>(); for (Planet p : planetList) { if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase())) nPlanetList.add(p); } results.values = nPlanetList; results.count = nPlanetList.size(); 1 2 3 4 5 6 7 8 9 10 11 12 13 @Override protected void publishResults(CharSequence constraint, FilterResults results) { // Now we have to inform the adapter about the new list filtered if (results.count == 0) notifyDataSetInvalidated(); else { planetList = (List<Planet>) results.values; notifyDataSetChanged(); } } 1 2 3 4 5 6 7 @Override public Filter getFilter() { if (planetFilter == null) planetFilter = new PlanetFilter(); return planetFilter; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:focusable="true" android:focusableInTouchMode="true"> <EditText android:id="@+id/editTxt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:maxLines="1" /> <ListView android:id="@+id/listView" android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1"/> <Button android:id="@+id/addBtn" android:text="Add planet" android:onClick="addPlanet" android:layout_weight="0.5" android:layout_height="80dp" ? ? ? ? ? converted by Web2PDFConvert.com
  • 3. Etichette: Filter, ListView, UI In the main activity we have to add some listener attached to EditText so that when user writes inside it we can filter the list items. Running the code we have: One simple trick we have to use is to make soft keyboard hidden at the app startup. As soon as the app starts the EditText gains the focus and the OS shows the keyboard covering the list items. If we don’t want this we can simply “move” the focus somewhere else: Source code here You might be interested on: Android ListView – Tutorial And Basic Example Android ListView : CustomAdapter And Layout More On ListView Filterable Interface 27 28 29 30 android:layout_width="match_parent"/> </LinearLayout> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 editTxt.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { System.out.println("Text ["+s+"]"); aAdpt.getFilter().filter(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); TRICKS 1 2 android:focusable="true" android:focusableInTouchMode="true" 46 comments Leave a message... BestBest CommunityCommunity Rohit • 2 months ago Hi Thanks a lot for this awesome tutorial.. I have successfully implemented it... 2973 8Google + 5 1 0DZone 0Reddit ? ? converted by Web2PDFConvert.com
  • 4. Reply Thanks a lot for this awesome tutorial.. I have successfully implemented it... But one question how do i implement in search widget and not using edit text I am going through http://developer.android.com/g... and also made the search widget... but how do i get edit text like id from it because search widget don't have any method as addTextChangedListener i suppose.. I am unable to make it through... can you help ? Reply survivingwithandroid • 2 months agoMod > Rohit I guess the approch is different. I will try to analyze your problem. Thank you Reply Rohit • 2 months ago> survivingwithandroid Thanks! pls give me some hint as to how to proceed .. I am really stuck :/ Reply dentex • 3 months ago Ciao, ho provato il codice da gitHub e funziona. Ma applicandolo al mio progetto, in cui ho implementato una mia versione di "Pianeta", il filtro non funziona. Il mio codice per la lista è basato sul custom adapter del tuo esempio "SimpleList". Non riesco a capire cosa può essere. In pratica quello che scrivo nell' EditText viene ignorato. Ho controllato tutto più volte... Qualche idea? Il codice del mio progetto è su https://github.com/dentex/ytdo... DashboardListItem.java DashboardActivity.java DashboardAdapter.java ciao e grazie comunque per gli ottimi tutorial. Reply survivingwithandroid • 3 months agoMod > dentex Adesso provo a scaricare il tuo progetto per vedere se riesco a capire xchè il filtro non va. 1 Reply dentex • 3 months ago> survivingwithandroid Grazie mille! non potevo sperare in niente di meglio. Reply dentex • 3 months ago> dentex ho appena constatato che sull'emulatore questa implementazione funziona anche nella mia app, così come l'avevo adattata. Quindi adesso devo cercare di capire perchè non funziona sul dispositivo reale... Spero di non averti fatto perdere tempo. dentex • 3 months ago> dentex Per la miseria funziona pure sul cellulare! Non ho toccato il codice, ho solo disinstallato la versione con la firma di Eclipse del portatile, e installato la versione dal desktop. Ieri ho perso una giornata... boh. Share › Share › Share › Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 5. Reply Reply survivingwithandroid • 3 months agoMod > dentex Probabilmente non aveva installato il codice corretto. Avevo dato un'occhiata al codice e mi sembrava corretto e non vedevo errori, quindi doveva funzionare! :) Reply dentex • 3 months ago> survivingwithandroid Forse ho capito perchè non mi ero accorto che funzionava: in pratica se digiti un carattere che dovrebbe escludere tu gli elementi della lista (cioè con cui nessun elemento inizia) non succede niente. Il filtro funziona solo se digiti qualcosa con cui effettivamente qualche elemento della lista inizia: es: - banana - mela - ciliegia se digito "d" la lista non viene modificata (o "x", o "y", ecc); se digito "m" vedo solo "mela" ecc. Inoltre ho riscontrato lo stesso problema del commento successivo riguardante i "listener": ritornano la posizione della lista non filtrata. (nell'esempio sopra, cliccando su mela "filtrata", si avrebbe comunque il riferimento a "banana"). ;) Reply survivingwithandroid • 3 months agoMod > dentex Per quanto riguarda il filtro con la lettera iniziale che non esiste e quindi la lista dovrebbe essere vuota mi sembra di averlo provato questo caso e funzionava. Per il secondo problema trovi qualche info sui commenti al post cmq il problema è che vai a prendere la posizione nella lista originale e non in quella filtrata. Reply dentex • 8 days ago> survivingwithandroid Per avere una lista "vuota" (cioè interamente filtrata) quando si inserisce un carattere con cui nessun elemento inizia, ho cambiato: public void publishResults(CharSequence constraint,FilterResults results) { if (results.count == 0) { notifyDataSetInvalidated(); } else { itemsList = (List<dashboardlistitem>) results.values; notifyDataSetChanged(); } } in: public void publishResults(CharSequence constraint,FilterResults results) { itemsList = (List<dashboardlistitem>) results.values; notifyDataSetChanged(); } </dashboardlistitem></dashboardlistitem> Reply dentex • 3 months ago> survivingwithandroid Grazie mille, sto cercando di risolvere! Ti faccio sapere. Share › Share › Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 6. Reply dentex • 3 months ago> dentex Ho risolto su come fare riferimento alla lista filtrata. (ho risposto alla discussione in basso) :D Reply Mick Hearne • 4 months ago Great Tutorial. Well explained. I used your code from Github and it filters my list fine. However, when I select a listItem it only shows me th first item in the list [0], even if it that item was filtered out. I am using onListItemClick, where you use onItemClick. from SQLite database and using Parcelable to send the data from the listview to a detail view. This is a project that's due in next week so a reply would be real nice. Thanks. Reply survivingwithandroid • 4 months agoMod > Mick Hearne If i get correctly when you use a filtered list and select one item of this list you get always the first one. If so i think you are using t original arraylist instead of the filtered array. Reply Mick Hearne • 4 months ago> survivingwithandroid Correct. I can't seem to select from the filtered list. Can you recommend a solution or is there a way I can get the source code to you? This is the Activity that uses the list *** And this is the adapter *** Thanks for the reply and hope to hear from you.... Reply survivingwithandroid • 4 months agoMod > Mick Hearne Well i noticed two things in onListItemClick: 1. You shouldn't call super.onList... because you are handling the event by yourself 2. You get the bird information from original birds list and not from the filtered one. So you should ask to the adapter the new birds array (the filtered one) and then get the bird data from it. Reply Mick Hearne • 4 months ago> survivingwithandroid Great, Thanks. I'll give it a go now. This is my first app and I'm just getting used to Android. Thanks again and I'll let you know how I got on... 1 Reply Mick Hearne • 4 months ago> Mick Hearne I've removed the super call and set the updated bird list in publishResults with notifyDataSetChanged. Still not working however. What am I missing here? I think I'm looking at this too long today, the answer is probably staring back at me.. 1 dentex • 3 months ago> Mick Hearne I found a solution on how to refer to the filtered list. Before calling any method on a list element, you have to take a reference to the modified list (using the names from the example given on this site): Planet currentPlanet = aAdpt.getItem(position); Share › Share › Share › Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 7. Reply where "position" is a parameter from, i.e.: public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { ... } Reply Anonymous • 6 months ago great tutorial.. Reply imran khan • 6 months ago Nice post.Give it up. Thanks for share this article. For more visit:android development Reply jfrankie • 8 months ago I posted how to solve the problem. Bye Reply Anonymous2 • 4 months ago> jfrankie thanks for this great tutorial but where did you post the solution? Reply survivingwithandroid • 4 months agoMod > Anonymous2 Look here http://www.survivingwithandroi... Reply Anonymous • 9 months ago Hi, code provided by you has been a great help while working on filtering custom list. Could you please also tell how to get back the names in the list as the user deletes characters in the search bar to return to the actual list. Any help would be appreciated. Reply Anonymous • 9 months ago Ok,thank you veru much ,I try with autocompletetextview and that's not working too. Reply jfrankie • 9 months ago Since you are populating your list using a JSON URL it could be wise to use an async adapter. It could be that your list isnt still populated wh you filter it. I suggest to you to try with a "static" items and verify that everything works then you move on and try to populate the list usi JSON. It could be useful to verify if item ids are stable there's a method to verify it. Anyway i will try to set up an example code that populates the list using a JSON and i will verify the result. Reading your code it seems everything is fine so the only one thing that is different from my example is the JSON URL. Anonymous • 9 months ago public void afficher_liste_gares(){ if(results!=null && results.size() > 0) { Share › Share › Share › Share › Share › Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 8. Reply see more adapter=new item_com_Choice(this, results); list4.setAdapter(adapter); //Teliste_vide_label.setVisibility(View.INVISIBLE); list4.setVisibility(View.VISIBLE); list4.setTextFilterEnabled(true); filterText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { System.out.println("Text ["+s+"]"); adapter.getFilter().filter(s.toString()); Reply see more Anonymous • 9 months ago public class item_com_Choice extends ArrayAdapter implements Filterable { private List planetList; private Context context; private Filter planetFilter; private List origPlanetList; public item_com_Choice(Context ctx,List planetList ) { super(ctx, R.layout.item4, planetList); this.planetList = planetList; this.context = ctx; this.origPlanetList = planetList; } @Override public int getCount() { return planetList.size(); } @Override Reply Anonymous • 9 months ago Thanks a lot ,but it still not working,when I write a letter in the EditText nothing happens...and I dont know why :( Reply Frankie JFrankie • 9 months ago The source code is available Anonymous • 9 months ago That still not working...I also override the toString method in the class "gare"...but it still not working :( @Override protected void publishResults(CharSequence constraint, FilterResults results) { item_com_list = (List) results.values; //Now we have to inform the adapter about the new list filtered if (results.count == 0) notifyDataSetInvalidated(); else { item_com_list = (List) results.values; Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 9. Reply item_com_list = (List) results.values; notifyDataSetChanged(); } Reply Frankie JFrankie • 9 months ago In the else part in the publish method you've to replace your code with: else { planetList = (List) results.values; notifyDataSetChanged(); } and remove it from the method. Reply see more Anonymous • 9 months ago public void afficher_liste_gares(){ if(results!=null && results.size() > 0) { final item_com_Choice adapter=new item_com_Choice(gare_choix_depart_activity.this, results); list4.setAdapter(adapter); //Teliste_vide_label.setVisibility(View.INVISIBLE); list4.setVisibility(View.VISIBLE); list4.setTextFilterEnabled(true); filterText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub System.out.println("Text ["+s+"]"); adapter.getFilter().filter(s.toString()); Reply see more Anonymous • 9 months ago Ok; Thank you very much. But the letter that I wrote is the first letter of a name of a "Station" in the data base This is the code source : private class gareFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); // We implement here the filter logic if (constraint == null || constraint.length() == 0) { // No filter implemented we return all the list results.values = item_com_list; results.count = item_com_list.size(); • 9 months Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 10. Reply Frankie JFrankie ago The filter works comparing the first letter so if you entered a letter that doens't match any items the result is empty. In a few hours i will add to github the entire source code so if you are patient you can try again. Reply Anonymous • 9 months ago Hi ; I tried this code but I had an empty result when I wrote a character and I dont know why Reply jfrankie • 10 months ago Well in this case you should replate startsWith with indexOf and verify that that letter is present so indexOf result is != -1 Reply Anonymous • 10 months ago I am using custom list Adapter in code.The listview is having indexbar.I need to show items whose words start with letters entered in searchbox i.e. if item is having 3 words and second word start with A and we enter A in searchbox then that item also should get searched Reply jfrankie • 10 months ago You can find me in g+ with survivingwithandroid. My email add is survivingwithandroid@gmail.com. Btw i downloaded your app and it looks great and i didn't find the error even if i filtered the list in the bus line option very very fast (I'm using Gingerbread). Anyway if you like you can send me the code so i can have an idea more detailed. The error seems caused by the fact you try to update the view from an external thread in that case you should somehow implements something like a queue. I'd really like to investigate more about it. Reply see more Ederson Schmidt • 10 months ago Hi, Thanks for ur answer. Well, this bug that u found I already fix some months ago. I fix with this code: @Override protected void publishResults(CharSequence constraint, FilterResults results) { planetList = (List) results.values; // Now we have to inform the adapter about the new list filtered if (results.count == 0) notifyDataSetInvalidated(); else { notifyDataSetChanged(); } } jfrankie • 10 months ago I tried to reproduce the error you told me...but even if i tried very fast with "a" and delete it the app didn't crash. I used 4.0.3 emulator. The only one bug i found is that the code doesn't show the complete list after you delete the filter in the edit view. This is caused by a mistake in the source code. You should create a copy of the original array showed in the listView and when the filter is empty set the value to this copy array. I will update the code. If you can repeat the error please send me the stack trace so i can have some clues. Share › Share › Share › Share › Share › Share › converted by Web2PDFConvert.com
  • 11. ALSO ONSURVIVING W/ ANDROID Android Face Detect 1 comment • 13 days ago Gabriel Pozoz — It's a topic on which there is not much written, thanks! Android app development :weather app with forecast 1 comment • 5 days ago AndroidDev101 — Thank you so much, this is amazing! Android Async ListView–JEE and RestFul 7 comments • 5 months ago survivingwithandroid — Ok. i will do it. Sorry for the delay Android ListView context menu: ActionMode.CallBack 1 comment • 5 months ago pavan — very nice tutorial Reply Reply jfrankie • 10 months ago Thanks for you comment. I will try to reproduce this bug and fix it and i will release a new source code version. Reply Ederson Schmidt • 10 months ago Nice work! I used it on my project, but I found a bug on this code. And it just found now, after I change my project android version to wo for 4.0.3 If I press "a" and delete.. repeat it very fast.. the app closes.. ListView need to be notified, that's the error message. But how to notify it again ? or how to avoid this bug ? Comment feedr Subscribe via email✉ Share › Share › Share › converted by Web2PDFConvert.com
  • 12. Newer Post Older Post Home Subscribe to: Post Comments (Atom) Online Nursing Programs WaldenU.edu/Nursing_Degrees Achieve A Higher Level Of Success! Enroll With Walden University Now Agile Development Tool pivotaltracker.com/agileproject Collaborative, Lightweight Agile Project Management Tool. Free Trial Online Master in MIS misdegree.businessdegrees.uab.edu Specialize in Web & Mobile App. Development - 100% Online. © 2012-2013 Survivingwithandroid.com Sitemap All Rights Reserved. Reproduction without explicit permission is prohibited. Android Blog Contact me About Me ►► 2013(25) ▼▼ 2012(19) ►► December(1) ►► November(3) ▼▼ October(3) Android ListView : Custom Filter and Filterable in... Android ListView : CustomAdapter and Layout Android ListView : ArrayAdapter, Manage Items, Use... ►► September(5) ►► August (1) ►► July (3) ►► June(3) BlogArchive Search SearchThis Blog Follow SwA Follow SwAbyEmail Email address... Submit Android ListView – Tutorial and basic example One of the UI component we use often is ListView, for example when we need to show items in a vertical scrolling list. One interesting asp... Android ListView : CustomAdapter and Layout Topics covered Android ListView Array Adapter Custom layout Optimization: View holder pattern In the last post , we talked about how ... Android ListView : Custom Filter and Filterable interface In the previous post we showed the way we can programming a custom adapter and a custom layout. One aspect we didn’t cover by now, is how w... Add a sliding menu with animation to anActivity I was playing around with animation, layers and so on and i have coded this simple sliding menu. The idea is very simple when user touches t... Android HTTP Client: GET, POST, Download, Upload, Multipart Request Topics covered HTTP connection Post request Download data Upload data Multipart request OftenAndroid apps have to exchange informati... Popular Posts converted by Web2PDFConvert.com
  • 13. Android weather app: JSON, HTTP and Openweathermap Topics covered How to develop weather app HTTP connection JSON Parsing OpenweathermapAPI In this post I want to describe how to creat... Android ListView with SectionIndexer and fast scroll In this post i want to analyze how to use ListView with SectionIndexer enabling the fast search. ListView has a method that enables the fa... Android ExpandableListView with CustomAdapter: BaseExpandableListAdapter Topics covered Android ExpandableListView BaseExpandableListAdapter Custom adapter In the previous post we talked about ListView and ho... Multi touch inAndroid : onTouchEvent example In this post i want to analyse howAndroid handles the multitouch. Reading some posts around the net i found that are a bit confusing and no... Fragment inAndroid: Tutorial with Example using WebView In this post we want to explain how to use fragment in Android with a real example . In the last post we talked about Fragment inAndroid... converted by Web2PDFConvert.com