Custom Listview Adapter with filter Android
You can use the Filterable
interface on your Adapter, have a look at the example below:
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(); } }}
In your Activity or Fragment where of Adapter is instantiated :
editTxt.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { System.out.println("Text ["+s+"]"); mSearchableAdapter.getFilter().filter(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { }});
Here are the links for the original source and another example
I hope it will be helpful for others.
// put below code (method) in Adapter classpublic void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); myList.clear(); if (charText.length() == 0) { myList.addAll(arraylist); } else { for (MyBean wp : arraylist) { if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) { myList.add(wp); } } } notifyDataSetChanged();}
declare below code in adapter class
private ArrayList<MyBean> myList; // for loading main listprivate ArrayList<MyBean> arraylist=null; // for loading filter data
below code in adapter Constructor
this.arraylist = new ArrayList<MyBean>(); this.arraylist.addAll(myList);
and below code in your activity class
final EditText searchET = (EditText)findViewById(R.id.search_et); // Capture Text in EditText searchET.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub String text = searchET.getText().toString().toLowerCase(Locale.getDefault()); adapter.filter(text); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } });
In your CustomAdapter class implement filterable.
public class CustomAdapter extends BaseAdapter implements Filterable { private List<ItemsModel> itemsModelsl; private List<ItemsModel> itemsModelListFiltered; private Context context; public CustomAdapter(List<ItemsModel> itemsModelsl, Context context) { this.itemsModelsl = itemsModelsl; this.itemsModelListFiltered = itemsModelsl; this.context = context; } @Override public int getCount() { return itemsModelListFiltered.size(); } @Override public Object getItem(int position) { return itemsModelListFiltered.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View view = getLayoutInflater().inflate(R.layout.row_items,null); TextView names = view.findViewById(R.id.name); TextView emails = view.findViewById(R.id.email); ImageView imageView = view.findViewById(R.id.images); names.setText(itemsModelListFiltered.get(position).getName()); emails.setText(itemsModelListFiltered.get(position).getEmail()); imageView.setImageResource(itemsModelListFiltered.get(position).getImages()); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e("main activity","item clicked"); startActivity(new Intent(MainActivity.this,ItemsPreviewActivity.class).putExtra("items",itemsModelListFiltered.get(position))); } }); return view; } @Override public Filter getFilter() { Filter filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); if(constraint == null || constraint.length() == 0){ filterResults.count = itemsModelsl.size(); filterResults.values = itemsModelsl; }else{ List<ItemsModel> resultsModel = new ArrayList<>(); String searchStr = constraint.toString().toLowerCase(); for(ItemsModel itemsModel:itemsModelsl){ if(itemsModel.getName().contains(searchStr) || itemsModel.getEmail().contains(searchStr)){ resultsModel.add(itemsModel); } filterResults.count = resultsModel.size(); filterResults.values = resultsModel; } } return filterResults; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { itemsModelListFiltered = (List<ItemsModel>) results.values; notifyDataSetChanged(); } }; return filter; }}
}
You can get the whole tutorial here:ListView With Search/Filter and OnItemClickListener