-
-
Save fjfish/3024308 to your computer and use it in GitHub Desktop.
<?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> |
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(); | |
} | |
} | |
} |
Thanks! In my case I want to pass its contents to next activity, so I did something like this
Intent i = new Intent(FirstActivity.this,SecondActivity.class);
i1.putExtra("main_title", filteredData.get(position));
i1.putExtra("sub_title", subTitle.get(position));
startActivity(i);
While filtering, 'main_title' is passing correctly to next activity, but 'sub_title' remains the same for all list items. How can I do the same for sub title?
I used your method but didn't any solution.please help me?
public class AddsAdapter extends ArrayAdapter implements Filterable
{
private LayoutInflater inflater;
public String imgstore="http://office.eastlinkhost.com/TrendMedia/banner/";
public static String imgurl="";
//public ImageLoader imageLoader;
private RequestQueue mRequestQueue;
private ImageLoader imageLoader;
private ItemFilter mFilter = new ItemFilter();
private List<addsinfo> originalData = null;
private List<addsinfo> filteredData = null;
public AddsAdapter(Context context,List<addsinfo> newsadapter)
{
super(context,R.layout.adds_listview,newsadapter);
// TODO Auto-generated constructor stub
inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//imageLoader=new ImageLoader(context.getApplicationContext());
// TODO Auto-generated constructor stub
this.filteredData = newsadapter ;
this.originalData = newsadapter ;
//mInflater = LayoutInflater.from(context);
}
public View getView(int postion,View contentView,ViewGroup parent)
{
View item=inflater.inflate(R.layout.view_all_listview,parent,false);
//TextView tv1=(TextView) item.findViewById(R.id.title);
TextView tv2=(TextView) item.findViewById(R.id.textView3);
TextView tv1=(TextView) item.findViewById(R.id.textView4);
ImageView img=(ImageView) item.findViewById(R.id.list_image);
//img.setBackgroundResource(R.anim.animations);
//AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
// Start the animation (looped playback by default).
//frameAnimation.start();
//creating the object of the student
addsinfo latestnews=getItem(postion);
//Log.d("latestnews", latestnews.ge());
//populate the custom list view with the class of Student
tv1.setText(latestnews.getVendor());
tv2.setText(latestnews.getPrice());
String image=latestnews.getImg();
imgurl=imgstore+image;
Log.d("imageurl", ""+imgurl);
//imageLoader.DisplayImage(imgurl, img);
img.setScaleType(ScaleType.FIT_XY);
//new DisplayImageFromURL((ImageView) item.findViewById(R.id.list_image)).execute(imgurl);
//mRequestQueue = Volley.newRequestQueue(getContext());
//imageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(
// BitmapLruCache.getDefaultLruCacheSize()));
//imageLoader.get(imgurl, ImageLoader.getImageListener(img,R.drawable.loading, //R.drawable.loading));
return item;
}
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 list = originalData;
int count = list.size();
final ArrayList<addsinfo> nlist = new ArrayList<addsinfo>(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 = (List<addsinfo>) results.values;
notifyDataSetChanged();
}
}
}
And in my MainActivity.java I used
private TextWatcher filterTextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
// adapter.notifyDataSetChanged();
// listofFriends.setAdapter(adapter);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
};
Hello your code helped me, but please how do i pass content from the filtered list to another activity? The onItemClick listener of the lisview still pass the original data,not the filtered one. Thanks
Hi, is it working? I might been using it in a wrong way.
Any help would be appreciated.
I'm calling it this way:
List datas = new ArrayList();
datas.add("France");
datas.add("localia");
datas.add("Rancia");
SearchableAdapter adapter = new SearchableAdapter(this, datas);
AddressBar.setAdapter(adapter);
But I'm getting:
07-18 02:01:38.160: E/AndroidRuntime(30618): java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
07-18 02:01:38.160: E/AndroidRuntime(30618): at SearchableAdapter.getCount(SearchableAdapter.java:42)
For some strange reason filteredData was null sometimes, causing the crash.
I solved changing this:
public int getCount() {
if(filteredData==null){
Log.v("LOG","Warn, null filteredData");
return 0;
}else{
return filteredData.size();
}
}
Helped me a lot! thanks :)
my list comes in a fragment. how can i implement this method there
your search functionality is working fine but your code makes list view empty when we remove all characters in search field. it should load all the default data again
Thank you! This helped me a lot!
Thank you.. And another thanks to "eiprol" for editing
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]
Helped me a lot. Thank you very much!