Created
June 30, 2012 15:48
-
-
Save fjfish/3024308 to your computer and use it in GitHub Desktop.
Simple String Adapter for Android ListView that has a filter that gives whatever it finds and ignores word boundaries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<TextView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/list_view" | |
android:layout_width="fill_parent" | |
android:layout_height="fill_parent" | |
android:padding="10dp" | |
android:textSize="16sp" > | |
</TextView> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.yourco.yourapp; | |
import java.util.ArrayList; | |
import java.util.List; | |
import android.content.Context; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.BaseAdapter; | |
import android.widget.Filter; | |
import android.widget.Filterable; | |
import android.widget.TextView; | |
// The standard text view adapter only seems to search from the beginning of whole words | |
// so we've had to write this whole class to make it possible to search | |
// for parts of the arbitrary string we want | |
public class SearchableAdapter extends BaseAdapter implements Filterable { | |
private List<String>originalData = null; | |
private List<String>filteredData = null; | |
private LayoutInflater mInflater; | |
private ItemFilter mFilter = new ItemFilter(); | |
public SearchableAdapter(Context context, List<String> data) { | |
this.filteredData = data ; | |
this.originalData = data ; | |
mInflater = LayoutInflater.from(context); | |
} | |
public int getCount() { | |
return filteredData.size(); | |
} | |
public Object getItem(int position) { | |
return filteredData.get(position); | |
} | |
public long getItemId(int position) { | |
return position; | |
} | |
public View getView(int position, View convertView, ViewGroup parent) { | |
// A ViewHolder keeps references to children views to avoid unnecessary calls | |
// to findViewById() on each row. | |
ViewHolder holder; | |
// When convertView is not null, we can reuse it directly, there is no need | |
// to reinflate it. We only inflate a new View when the convertView supplied | |
// by ListView is null. | |
if (convertView == null) { | |
convertView = mInflater.inflate(R.layout.list_item, null); | |
// Creates a ViewHolder and store references to the two children views | |
// we want to bind data to. | |
holder = new ViewHolder(); | |
holder.text = (TextView) convertView.findViewById(R.id.list_view); | |
// Bind the data efficiently with the holder. | |
convertView.setTag(holder); | |
} else { | |
// Get the ViewHolder back to get fast access to the TextView | |
// and the ImageView. | |
holder = (ViewHolder) convertView.getTag(); | |
} | |
// If weren't re-ordering this you could rely on what you set last time | |
holder.text.setText(filteredData.get(position)); | |
return convertView; | |
} | |
static class ViewHolder { | |
TextView text; | |
} | |
public Filter getFilter() { | |
return mFilter; | |
} | |
private class ItemFilter extends Filter { | |
@Override | |
protected FilterResults performFiltering(CharSequence constraint) { | |
String filterString = constraint.toString().toLowerCase(); | |
FilterResults results = new FilterResults(); | |
final List<String> list = originalData; | |
int count = list.size(); | |
final ArrayList<String> nlist = new ArrayList<String>(count); | |
String filterableString ; | |
for (int i = 0; i < count; i++) { | |
filterableString = list.get(i); | |
if (filterableString.toLowerCase().contains(filterString)) { | |
nlist.add(filterableString); | |
} | |
} | |
results.values = nlist; | |
results.count = nlist.size(); | |
return results; | |
} | |
@SuppressWarnings("unchecked") | |
@Override | |
protected void publishResults(CharSequence constraint, FilterResults results) { | |
filteredData = (ArrayList<String>) results.values; | |
notifyDataSetChanged(); | |
} | |
} | |
} |
Amazing!!! A small edit,
public int getCount() {
return filteredData == null ? 0 : filteredData.size();
}
Perfect now :)
But when I do BackSpace, it is sorting until it has at least one character. On deleting the entire data, drop down is not shown. and when I click it again drop down is not coming.
WHYYYYYYYYYYY???????
@ganesh76 How do we show the default list when text is removed. Do you have any solution for this?
@prathibhaprabs You must update the results.values with the reference to the original data.
I've done this with the code below, before the for:
if (filterString.isEmpty()) {
results.values = list;
results.count = list.size();
return results;
}
Thank you!!
Thanks a lot!! This helped me so much!
Thanks
[simple star or follow button could have omitted this unwanted comment]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you.. And another thanks to "eiprol" for editing