How to use search functionality in custom list view in Android How to use search functionality in custom list view in Android android android

How to use search functionality in custom list view in Android


You have to use model, listview, and customadapter with filtering for this.I have created a demo for this.

Suppose you have a model named Product, and you are displaying its content in a custom listview where name and price are displayed in a textview. I mean in a custom row having two textviews, and you want to filter the list by one of the field of custom row. Here I have filtered with "name"

Screenshots:

Initial

Initial

Filtered

Filtered

Source code

Model

public class Product {    public String name;    public Integer price;    public Product(String name, Integer price) {        super();        this.name = name;        this.price = price;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Integer getPrice() {        return price;    }    public void setPrice(Integer price) {        this.price = price;    }}

Activity with custom adapter and listview

public class MainActivity extends Activity {    private LinearLayout llContainer;    private EditText etSearch;    private ListView lvProducts;    private ArrayList<Product> mProductArrayList = new ArrayList<Product>();    private MyAdapter adapter1;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initialize();        // Add Text Change Listener to EditText        etSearch.addTextChangedListener(new TextWatcher() {            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                // Call back the Adapter with current character to Filter                adapter1.getFilter().filter(s.toString());            }            @Override            public void beforeTextChanged(CharSequence s, int start, int count,int after) {            }            @Override            public void afterTextChanged(Editable s) {            }        });    }    private void initialize() {        etSearch = (EditText) findViewById(R.id.etSearch);        lvProducts = (ListView)findViewById(R.id.lvOS);    }    @Override    protected void onResume() {        // TODO Auto-generated method stub        super.onResume();        mProductArrayList.add(new Product("a", 100));        mProductArrayList.add(new Product("b", 200));        mProductArrayList.add(new Product("c", 300));        mProductArrayList.add(new Product("d", 400));        mProductArrayList.add(new Product("e", 500));        mProductArrayList.add(new Product("f", 600));        mProductArrayList.add(new Product("g", 700));        mProductArrayList.add(new Product("h", 800));        mProductArrayList.add(new Product("i", 900));        mProductArrayList.add(new Product("j", 1000));        mProductArrayList.add(new Product("k", 1100));        mProductArrayList.add(new Product("l", 1200));        mProductArrayList.add(new Product("m", 1000));        mProductArrayList.add(new Product("n", 1300));        mProductArrayList.add(new Product("o", 1400));        mProductArrayList.add(new Product("p", 1500));        adapter1 = new MyAdapter(MainActivity.this, mProductArrayList);        lvProducts.setAdapter(adapter1);    }    // Adapter Class                public class MyAdapter extends BaseAdapter implements Filterable {        private ArrayList<Product> mOriginalValues; // Original Values        private ArrayList<Product> mDisplayedValues;    // Values to be displayed        LayoutInflater inflater;        public MyAdapter(Context context, ArrayList<Product> mProductArrayList) {            this.mOriginalValues = mProductArrayList;            this.mDisplayedValues = mProductArrayList;            inflater = LayoutInflater.from(context);        }        @Override        public int getCount() {            return mDisplayedValues.size();        }        @Override        public Object getItem(int position) {            return position;        }        @Override        public long getItemId(int position) {            return position;        }        private class ViewHolder {            LinearLayout llContainer;            TextView tvName,tvPrice;        }        @Override        public View getView(final int position, View convertView, ViewGroup parent) {            ViewHolder holder = null;            if (convertView == null) {                holder = new ViewHolder();                convertView = inflater.inflate(R.layout.row, null);                holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer);                holder.tvName = (TextView) convertView.findViewById(R.id.tvName);                holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice);                convertView.setTag(holder);            } else {                holder = (ViewHolder) convertView.getTag();            }            holder.tvName.setText(mDisplayedValues.get(position).name);            holder.tvPrice.setText(mDisplayedValues.get(position).price+"");            holder.llContainer.setOnClickListener(new OnClickListener() {                public void onClick(View v) {                    Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show();                }            });            return convertView;        }        @Override        public Filter getFilter() {            Filter filter = new Filter() {                @SuppressWarnings("unchecked")                @Override                protected void publishResults(CharSequence constraint,FilterResults results) {                    mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values                    notifyDataSetChanged();  // notifies the data with new filtered values                }                @Override                protected FilterResults performFiltering(CharSequence constraint) {                    FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values                    ArrayList<Product> FilteredArrList = new ArrayList<Product>();                    if (mOriginalValues == null) {                        mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues                    }                    /********                     *                      *  If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values                     *  else does the Filtering and returns FilteredArrList(Filtered)                       *                     ********/                    if (constraint == null || constraint.length() == 0) {                        // set the Original result to return                          results.count = mOriginalValues.size();                        results.values = mOriginalValues;                    } else {                        constraint = constraint.toString().toLowerCase();                        for (int i = 0; i < mOriginalValues.size(); i++) {                            String data = mOriginalValues.get(i).name;                            if (data.toLowerCase().startsWith(constraint.toString())) {                                FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price));                            }                        }                        // set the Filtered result to return                        results.count = FilteredArrList.size();                        results.values = FilteredArrList;                    }                    return results;                }            };            return filter;        }    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <EditText         android:id="@+id/etSearch"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        />    <ListView         android:id="@+id/lvProducts"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        ></ListView>    </LinearLayout>

row.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/llContainer"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <TextView         android:id="@+id/tvName"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:singleLine="true"        android:layout_weight="1"        />    <TextView         android:id="@+id/tvPrice"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:singleLine="true"        android:layout_weight="1"        /></LinearLayout>


Implement filterable in your customadapter class.listviewenter image description here

public class MainActivity extends AppCompatActivity {String names[] = {"Apple","Banana","Kiwi","Oranges","Watermelon"};String emails[] = {"This is apple","This is banana","This is kiwi","This is oranges","This is watermelon"};int images[] = {R.drawable.apple,R.drawable.banana,R.drawable.kiwi,R.drawable.oranges,R.drawable.watermelon};List<ItemsModel> itemsModelList = new ArrayList<>();ListView listView;CustomAdapter customAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    listView = findViewById(R.id.listview);    for(int i = 0;i < names.length;i++){        ItemsModel itemsModel = new ItemsModel(names[i],emails[i],images[i]);        itemsModelList.add(itemsModel);    }     customAdapter = new CustomAdapter(itemsModelList,this);    listView.setAdapter(customAdapter);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.search_menu,menu);    MenuItem menuItem = menu.findItem(R.id.searchView);    SearchView searchView = (SearchView) menuItem.getActionView();    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {        @Override        public boolean onQueryTextSubmit(String query) {            return false;        }        @Override        public boolean onQueryTextChange(String newText) {            Log.e("Main"," data search"+newText);            customAdapter.getFilter().filter(newText);            return true;        }    });    return true;}@Overridepublic boolean onOptionsItemSelected(@NonNull MenuItem item) {    int id = item.getItemId();    if(id == R.id.searchView){        return true;    }    return super.onOptionsItemSelected(item);}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;    }}

}

full tutorial can be found here:listview with search and onItemClickListner


for this, you first need to add an edittext, where you will type to filter data from the list,

then enable filteration in the list,

editText = (EditText) findViewById(R.id.searchList); adapter = new CustomListViewAdapter(this,                R.layout.list_row, rowItems);        listView.setAdapter(adapter);        listView.setTextFilterEnabled(true);

Then you need to add TextChangeListener() for the edittext,

editText.addTextChangedListener(new TextWatcher() {            public void onTextChanged(CharSequence arg0, int arg1, int arg2,                    int arg3) {            }            public void beforeTextChanged(CharSequence arg0, int arg1,                    int arg2, int arg3) {            }            public void afterTextChanged(Editable arg0) {                MyActivityName.this.adapter.getFilter().filter(arg0);            }        });