Hi Guys, Welcome to Proto Coders Point, In this android tutorial article we will learn how to add a Search filter to a RecycleView in Toolbar SearchView in Real-time.
Video Tutorial on filter recyclerview android using SearchView
Android Recyclerview Adapter Filterable – Android search filter
Required Dependencies
implementation 'androidx.recyclerview:recyclerview:1.1.0' //recycleview implementation 'androidx.cardview:cardview:1.0.0'
Add both of the above dependencies in your app.level build.gradle file under dependencies.
To achieve this feature, First, you need to create a menu item in your android project.
Steps to create a menu item in android
In your android project > res > create a new package(folder) name it as “menu”,
Then, in the menu package create an XML file “search_menu.xml”
search_menu.xml
Then, Add the following code to the menu.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:icon="@drawable/ic_search" android:title="Search" app:actionViewClass="android.widget.SearchView" app:showAsAction="ifRoom|collapseActionView" /> </menu>
Here, In the above code, the menu is given an id, an Icon (a search icon, you need to create a vector search image in your drawable folder),
And to make it expandable I am using shows action with collapseActionView attribute, By doing this we can the menu as an icon in our android app bar when this icon is been pressed/clicked it will expand, and hence the user can input text in Android SearchView.
Add some images
You need to add some images under the drawable folder so that you can show images in your recycler view cards.
Eg: In my case, I have just created few vector images in my drawable, you can see in the below screenshot
Now, let’s procedure in creating a Recyclerview with Filterable search filter – android filter recycler view using search view in toolbar
Custom layout for RecyclerView
custom_layout_for_recyclerview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp" android:id="@+id/game_id" app:cardBackgroundColor="#E8E0E0" app:cardCornerRadius="15dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:orientation="horizontal"> <ImageView android:id="@+id/imageview" android:layout_width="80dp" android:layout_height="80dp" /> <TextView android:id="@+id/tvName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name" android:textSize="30sp" android:textColor="@color/black" android:layout_marginLeft="25dp" android:layout_gravity="center"/> </LinearLayout> </androidx.cardview.widget.CardView> </LinearLayout>
In this custom layout for recycler view, we have 2 views i.e. ImageView & a TextView, Where we will display our Data Model Data in a form of recyclerview.
Data Model that hold List of Data’s
ItemDataModel.java
package com.example.recycleviewexample.DataModel; public class ItemDataModel { int image; String txtname; public ItemDataModel(int image, String txtname) { this.image = image; this.txtname = txtname; } public int getImage() { return image; } public String getTxtname() { return txtname; } }
Recyclerview Adapter
Then, we need a RecyclerView Adapter that will help us in creating views and show a list of data in recycleview.
Here, In the below lines of codes, We Implement a Filterable interface into our RecyclerView Adapter class and then create our own Filter Method, Where we are applying filtering logic using perform filtering method which will filter return result to publishresult method and then apply the searched Filter data and show it to the user on the RecyclerViewscreen.
There I am using 2 array list,
First One holds a complete ArrayList of data’s and
the second holds the only ArrayList of Data that a user search in the SearchView Search Filter.
RecyclerAdapter.java
package com.example.recycleviewexample.Adapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.example.recycleviewexample.DataModel.ItemDataModel; import com.example.recycleviewexample.R; import java.util.ArrayList; public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.MyViewHolder> implements Filterable { private ArrayList<ItemDataModel> dataSet; private ArrayList<ItemDataModel> FullList; class MyViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView tvName; MyViewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.imageview); tvName = itemView.findViewById(R.id.tvName); } } public RecycleAdapter(ArrayList<ItemDataModel> itemList) { this.dataSet = itemList; FullList = new ArrayList<>(itemList); } @NonNull @Override public RecycleAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_layout_for_recyclerview, parent, false); return new MyViewHolder(v); } @Override public void onBindViewHolder(@NonNull RecycleAdapter.MyViewHolder holder, int position) { ItemDataModel currentItem = dataSet.get(position); holder.imageView.setImageResource(currentItem.getImage()); holder.tvName.setText(currentItem.getTxtname()); } @Override public int getItemCount() { return dataSet.size(); } @Override public Filter getFilter() { return Searched_Filter; } private Filter Searched_Filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList<ItemDataModel> filteredList = new ArrayList<>(); if (constraint == null || constraint.length() == 0) { filteredList.addAll(FullList); } else { String filterPattern = constraint.toString().toLowerCase().trim(); for (ItemDataModel item : FullList) { if (item.getTxtname().toLowerCase().contains(filterPattern)) { filteredList.add(item); } } } FilterResults results = new FilterResults(); results.values = filteredList; return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { dataSet.clear(); dataSet.addAll((ArrayList) results.values); notifyDataSetChanged(); } }; }
MainActivity.java
Then, In our MainActivity, we are creating a List of Data and passing the data to RecyclerView Adaptor to display them,
To show a Search View Menu in our App Toolbar we are using @Override onCreateOptionsMenu where we will use MenuInflater to show Search Menu,
Then connect our SearchView with our Menu Search,
using setOnQueryTextListener we are detecting onQueryTextChange where user enter Search Filter String we will pass to the string to our adapter method (adapter.getFilter().filter(newText))
Then our adapter method will create new dataSet and display the searched data to the user.
MainActivity.java
package com.example.recycleviewexample; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.inputmethod.EditorInfo; import android.widget.SearchView; import com.example.recycleviewexample.Adapter.RecycleAdapter; import com.example.recycleviewexample.DataModel.ItemDataModel; import java.lang.reflect.Array; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private RecycleAdapter adapter; private ArrayList<ItemDataModel> dataSet; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fillExampleList(); setUpRecyclerView(); } private void fillExampleList() { dataSet = new ArrayList<>(); dataSet.add(new ItemDataModel(R.drawable.computer, "Computer 1")); dataSet.add(new ItemDataModel(R.drawable._self_improvement, "Meditation 1")); dataSet.add(new ItemDataModel(R.drawable.rowing, "Rowing 1")); dataSet.add(new ItemDataModel(R.drawable.running, "Running 2")); dataSet.add(new ItemDataModel(R.drawable.rowing, "Rowing 2")); dataSet.add(new ItemDataModel(R.drawable.computer, "Computer 2")); dataSet.add(new ItemDataModel(R.drawable.running, "Running 2")); dataSet.add(new ItemDataModel(R.drawable._self_improvement, "Meditation 2")); dataSet.add(new ItemDataModel(R.drawable.running, "Running 3")); } private void setUpRecyclerView() { RecyclerView recyclerView = findViewById(R.id.recycle_view); recyclerView.setHasFixedSize(true); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); adapter = new RecycleAdapter(dataSet); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.search_menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { Log.d("newText1",query); return false; } @Override public boolean onQueryTextChange(String newText) { Log.d("newText",newText); adapter.getFilter().filter(newText); return false; } }); return true; } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#e0dfdf" android:orientation="vertical" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycle_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="81" android:scrollbars="vertical" /> </LinearLayout>
Recommended Android articles
Send user-entered recyclerview edit text Array list data to database (PHPMyAdmin)
Recyclerview with card view android example – Android X Tutorial
RecyclerView With GridLayoutManager Show Grid View in androidx
Firebase UI RecyclerView Adapter Android Tutorial with Example
[…] How to add search filter to recyclerview adapter. […]