This demo will show you how you can filter a RecyclerView with your Custom Objects.

If you are new to RecyclerView, then please go through this post to get a glance.

Check out the Demo Video ( 7 seconds)

RecyclerView Filter

Here I am using a CustomClass called “ListItem” which has three members.

ListItem

package com.coderzheaven.filterlistview;

public class ListItem {
    String name, place;
    int logo;

    public void setData(String name, String place, int logo) {
        this.name = name;
        this.place = place;
        this.logo = logo;
    }
}

MainActivity

package com.coderzheaven.filterlistview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {

    private static final String TAG = "MainActivity";
    private ArrayList<ListItem> allList;

    private RecyclerView mRecyclerView;
    private MyRecyclerAdapter adapter;
    private SearchView mSearchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSearchView = (SearchView) findViewById(R.id.search_view);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        setList();

        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        adapter = new MyRecyclerAdapter(this, allList);
        mRecyclerView.setAdapter(adapter);

        setupSearchView();
    }

    public void setList() {

        allList = new ArrayList<ListItem>();

        ListItem item = new ListItem();
        item.setData("Google", "USA", R.drawable.google);
        allList.add(item);

        item = new ListItem();
        item.setData("Apple", "USA", R.drawable.apple);
        allList.add(item);

        item = new ListItem();
        item.setData("Samsung", "Korea", R.drawable.samsung);
        allList.add(item);

        item = new ListItem();
        item.setData("Sony", "Japan", R.drawable.sony);
        allList.add(item);

        item = new ListItem();
        item.setData("HTC", "Taiwan", R.drawable.htc);
        allList.add(item);

        for (int i = 0; i < 10000; i++) {
            item = new ListItem();
            item.setData("Google " + i, "USA " + i, R.drawable.google);
            allList.add(item);
        }

    }

    private void setupSearchView() {
        mSearchView.setIconifiedByDefault(false);
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setSubmitButtonEnabled(true);
        mSearchView.setQueryHint("Search Here");
    }

    public boolean onQueryTextChange(String newText) {
        adapter.filter(newText);
        return true;
    }

    public boolean onQueryTextSubmit(String query) {
        return false;
    }

}

We have added around 10000 custom items in the RecyclerView for searching.

Now we will see the “RecyclerView” which also includes searching.

MyRecyclerAdapter

package com.coderzheaven.filterlistview;

import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyCustomViewHolder> {

    private List<ListItem> listItems, filterList;
    private Context mContext;

    public MyRecyclerAdapter(Context context, List<ListItem> listItems) {
        this.listItems = listItems;
        this.mContext = context;
        this.filterList = new ArrayList<ListItem>();
        // we copy the original list to the filter list and use it for setting row values
        this.filterList.addAll(this.listItems);
    }

    @Override
    public MyCustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_item, null);
        MyCustomViewHolder viewHolder = new MyCustomViewHolder(view);
        return viewHolder;

    }

    @Override
    public void onBindViewHolder(MyCustomViewHolder customViewHolder, int position) {

        ListItem listItem = filterList.get(position);
        customViewHolder.tvName.setText(listItem.name);
        customViewHolder.tvPlace.setText(listItem.place);
        customViewHolder.imgThumb.setBackgroundResource(listItem.logo);

    }

    @Override
    public int getItemCount() {
        return (null != filterList ? filterList.size() : 0);
    }
    
    // Do Search...
    public void filter(final String text) {

        // Searching could be complex..so we will dispatch it to a different thread...
        new Thread(new Runnable() {
            @Override
            public void run() {

                // Clear the filter list
                filterList.clear();

                // If there is no search value, then add all original list items to filter list
                if (TextUtils.isEmpty(text)) {

                    filterList.addAll(listItems);

                } else {
                    // Iterate in the original List and add it to filter list...
                    for (ListItem item : listItems) {
                        if (item.name.toLowerCase().contains(text.toLowerCase()) ||
                                item.place.toLowerCase().contains(text.toLowerCase())) {
                            // Adding Matched items
                            filterList.add(item);
                        }
                    }
                }

                // Set on UI Thread
                ((Activity) mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // Notify the List that the DataSet has changed...
                        notifyDataSetChanged();
                    }
                });

            }
        }).start();

    }

}

MyCustomViewHolder

package com.coderzheaven.filterlistview;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

public class MyCustomViewHolder extends RecyclerView.ViewHolder {

    protected ImageView imageView;
    protected TextView tvName, tvPlace;
    protected ImageView imgThumb;

    public MyCustomViewHolder(View view) {
        super(view);
        this.tvName = (TextView) view.findViewById(R.id.tvName);
        this.tvPlace = (TextView) view.findViewById(R.id.tvPlace);
        this.imgThumb = (ImageView) view.findViewById(R.id.imgThumb);
    }

}

You could check my RecyclerView post to check the layout XMLs and update the layout ids as well.

Download the complete Android Studio Source Code from here.

 

9 Comments

  1. dondeepak April 10, 2017 at 12:30 pm

    hai, i tried to use your code but when i open main activity page is empty but when i type something and delete in search box only after list is loading. please help

     
    • James April 14, 2017 at 5:47 pm

      Hi dondeepak, Is it working now?

       
      • Saurabh Sarpotdar April 23, 2017 at 6:57 am

        It is still not working…means all the items are visible only when I type something in the searchview and then clear it…and after that i can have normal implementation.. but at the start why all the items are not appearing.?

         
        • James April 30, 2017 at 6:56 am

          You can change the logic anyway you want.
          There is no value in the textbox when the app starts.

           
        • Darpan K August 10, 2017 at 6:48 am

          Change this:

          @Override
          public int getItemCount() {
          return (null != filterList ? filterList.size() : 0);
          }

          to:

          @Override
          public int getItemCount() {
          return (null != filterList ? filterList.size() : listItems.size());
          }

          or:

          @Override
          public int getItemCount() {
          if(filterList.size() != 0)
          return filterLIst.size();
          else
          return listItems.size();
          }

           
  2. amin April 16, 2017 at 9:25 pm

    it works perfect & thank you for sharing

     
    • Hardeep Singh May 21, 2017 at 12:47 pm

      Nice tutorial. But am facing same issue as discussed by other users. All the items are visible only when I type something in the searchview and then clear it. I think some change need to be done here:
      public int getItemCount() {
      return (null != filterList ? filterList.size() : 0);
      }
      Kindly reply. I need all the items to be displayed once fragment is created.

       
      • James May 27, 2017 at 3:55 pm

        Yeah, you could change the logic based on the requirement.
        If the filtercount is zero, you could add all items in the original array list to filter list and call notifyDatasetChanged() method to view all the items.

         
  3. Samir Samedov July 14, 2017 at 2:30 pm

    You are beautifull my friend thank you

     

Leave a Reply

Your email address will not be published. Required fields are marked *

 

 

 

Theme by HermesThemes

Copyright © 2018 CoderzHeaven. All Rights Reserved

Please wait...

Subscribe to our newsletter

Want to be notified when our article is published? Enter your email address and name below to be the first to know.