Filtering a RecyclerView with Custom Objects.

By | May 13, 2016

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.java

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.java

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.java

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.java

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.

Leave a Reply

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