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)
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.
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
Hi dondeepak, Is it working now?
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.?
You can change the logic anyway you want.
There is no value in the textbox when the app starts.
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();
}
it works perfect & thank you for sharing
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.
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.
You are beautifull my friend thank you