Android Recyclerview Search example tutorial will guide you to implement or add search filter functionality in ReyclerView.
In the scenarios where there are many items listed with ReyclerView, we need to put search filter functionality.
It let the user find his desired information quickly and easily.
You will learn with two examples.
1. Android SearchView Tutorial With RecyclerView
2. Android RecyclerView Search Filter Functionality With EditText
1. Android SearchView Tutorial With RecyclerView
First, check the output of Android RecyclerView SearchView and then go ahead for implementing yourself.
Step 1: Updating build.gradle(Module:app) file
Add below source code into dependencies{}
compile 'com.android.support:recyclerview-v7:23.4.0' compile 'com.android.support:cardview-v7:23.3.+'
Step 2: Coding cardview.xml
Create a new file into drawable folder and name it cardview.xml
Add below source code into it.
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true"> <shape android:shape="rectangle"> <padding android:left="4dp" android:top="4dp" android:right="4dp" android:bottom="4dp" /> <gradient android:startColor="#b71ca2" android:endColor="#cc2ec1" android:angle="270" /> <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"/> </shape> </item> <item android:state_focused="false" > <shape android:shape="rectangle"> <padding android:left="4dp" android:top="4dp" android:right="4dp" android:bottom="4dp" /> <gradient android:startColor="#b71ca2" android:endColor="#cc2ec1" android:angle="270" /> <corners android:topLeftRadius="4dp" android:topRightRadius="4dp" /> </shape> </item> </selector>
Step 3: Making rv_item.xml
Create a new layout resource file named rv_item.xml
Copy following source code into it
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="0dp" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv2" android:height="40dp" android:background="@drawable/cardview" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="" android:textColor="#fff" android:textStyle="bold" android:textSize="18sp" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv" android:height="40dp" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="Image" android:textColor="#000" android:textStyle="bold" android:textSize="18sp" /> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout>
Step 4: Making Model class
Create a new JAVA class named Model.java and paste below source code
/** * Created by Parsania Hardik on 28-Jun-17. */ public class Model { private String name; private int image_drawable; public String getName() { return name; } public void setName(String name) { this.name = name; } }
Step 5: Code for Adapter.java
Let’s create Custom Adapter for RecyclerView.
Make a new JAVA class named Adapter.java and paste below
import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.Locale; /** * Created by Parsania Hardik on 26-Jun-17. */ public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> { private LayoutInflater inflater; private ArrayList<Model> imageModelArrayList; private ArrayList<Model> arraylist; public Adapter(Context ctx, ArrayList<Model> imageModelArrayList){ inflater = LayoutInflater.from(ctx); this.imageModelArrayList = imageModelArrayList; this.arraylist = new ArrayList<Model>(); this.arraylist.addAll(MainActivity.imageModelArrayList); } @Override public Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.rv_item, parent, false); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(Adapter.MyViewHolder holder, int position) { holder.time.setText(imageModelArrayList.get(position).getName()); } @Override public int getItemCount() { return imageModelArrayList.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ TextView time; public MyViewHolder(View itemView) { super(itemView); time = (TextView) itemView.findViewById(R.id.tv); } } // Filter Class public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); MainActivity.imageModelArrayList.clear(); if (charText.length() == 0) { MainActivity.imageModelArrayList.addAll(arraylist); } else { for (Model wp : arraylist) { if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) { MainActivity.imageModelArrayList.add(wp); } } } notifyDataSetChanged(); } }
Step 6: Understanding Main Logic
Look at below filter method, which is from adapter class
// Filter Class public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); MainActivity.imageModelArrayList.clear(); if (charText.length() == 0) { MainActivity.imageModelArrayList.addAll(arraylist); } else { for (Model wp : arraylist) { if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) { MainActivity.imageModelArrayList.add(wp); } } } notifyDataSetChanged(); }
Here main logic for filtering the recyclerview items are present.
When user enters the query, this method is called.
This method will change the arrayList of model class according to search query and recyclerview will be updated with new arrayList of model class.
Step 7: Update Main Activity
Finally Update activity_main.xml and MainActivity.java files.
Updating activity_main.xml
Make following code into activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <SearchView android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:iconifiedByDefault="false"> <requestFocus /> </SearchView> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="15dp"/> </LinearLayout>
Updating MainActivity.java
Copy following into MainActivity.java
import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.SearchView; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener { private RecyclerView recyclerView; public static ArrayList<Model> imageModelArrayList; private Adapter adapter; private SearchView editsearch; private String[] myImageNameList = new String[]{"Benz", "Bike", "Car","Carrera" ,"Ferrari","Harly", "Lamborghini","Silver"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView) findViewById(R.id.recycler); imageModelArrayList = populateList(); Log.d("hjhjh", imageModelArrayList.size() + ""); adapter = new Adapter(this,imageModelArrayList); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false)); recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new ClickListener() { @Override public void onClick(View view, int position) { Toast.makeText(MainActivity.this, imageModelArrayList.get(position).getName(), Toast.LENGTH_SHORT).show(); } @Override public void onLongClick(View view, int position) { } })); editsearch = (SearchView) findViewById(R.id.search); editsearch.setOnQueryTextListener(this); } @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { String text = newText; adapter.filter(text); return false; } private ArrayList<Model> populateList(){ ArrayList<Model> list = new ArrayList<>(); for(int i = 0; i < 8; i++){ Model imageModel = new Model(); imageModel.setName(myImageNameList[i]); list.add(imageModel); } return list; } public interface ClickListener { void onClick(View view, int position); void onLongClick(View view, int position); } static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { private GestureDetector gestureDetector; private ClickListener clickListener; public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) { this.clickListener = clickListener; gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null) { clickListener.onLongClick(child, recyclerView.getChildPosition(child)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { clickListener.onClick(child, rv.getChildPosition(child)); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } } }
So it was all for Android RecyclerView SearchView tutorial.
2. Android RecyclerView Search Filter Functionality With EditText
Android RecyclerView Search Filter Functionality Example Tutorial is present at your service.
Android RecyclerView Search Filter example guide you to implement search functionality in RecyclerView Using EditText.
We will use Android Studio to develop Android RecyclerView Search Filter tutorial.
We will also implement onItemClickListener on searched results.
First, check the output of this Android RecyclerView Search Filter tutorial in below video.
Step 1: Updating build.gradle(Module:app) file
Copy following source code into dependencies{}
compile 'com.android.support:recyclerview-v7:23.4.0' compile 'com.android.support:cardview-v7:23.3.+'
Step 2: Coding cardview.xml
Create a new file into drawable folder and name it cardview.xml
Add below source code into it.
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true"> <shape android:shape="rectangle"> <padding android:left="4dp" android:top="4dp" android:right="4dp" android:bottom="4dp" /> <gradient android:startColor="#b71ca2" android:endColor="#cc2ec1" android:angle="270" /> <corners android:topLeftRadius="4dp" android:topRightRadius="4dp"/> </shape> </item> <item android:state_focused="false" > <shape android:shape="rectangle"> <padding android:left="4dp" android:top="4dp" android:right="4dp" android:bottom="4dp" /> <gradient android:startColor="#b71ca2" android:endColor="#cc2ec1" android:angle="270" /> <corners android:topLeftRadius="4dp" android:topRightRadius="4dp" /> </shape> </item> </selector>
Step 3: Making rv_item.xml
Create a new layout resource file named rv_item.xml
Copy following source code into it
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="0dp" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv2" android:height="40dp" android:background="@drawable/cardview" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="" android:textColor="#fff" android:textStyle="bold" android:textSize="18sp" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/tv" android:height="40dp" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="Image" android:textColor="#000" android:textStyle="bold" android:textSize="18sp" /> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout>
Step 4: Making Model class
Create a new JAVA class named Model.java and paste below source code
/** * Created by Parsania Hardik on 28-Jun-17. */ public class Model { private String name; private int image_drawable; public String getName() { return name; } public void setName(String name) { this.name = name; } }
Step 5: Code for Adapter.java
Let’s create Custom Adapter for RecyclerView.
Make a new JAVA class named Adapter.java and paste below
import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; /** * Created by Parsania Hardik on 26-Jun-17. */ public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> { private LayoutInflater inflater; private ArrayList<Model> imageModelArrayList; private ArrayList<Model> arraylist; public Adapter(Context ctx, ArrayList<Model> imageModelArrayList){ inflater = LayoutInflater.from(ctx); this.imageModelArrayList = imageModelArrayList; this.arraylist = new ArrayList<Model>(); this.arraylist.addAll(MainActivity.movieNamesArrayList); } @Override public Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.rv_item, parent, false); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(Adapter.MyViewHolder holder, int position) { holder.time.setText(imageModelArrayList.get(position).getName()); } @Override public int getItemCount() { return imageModelArrayList.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ TextView time; public MyViewHolder(View itemView) { super(itemView); time = (TextView) itemView.findViewById(R.id.tv); } } }
Step 6: Update Main Activity
Finally Update activity_main.xml and MainActivity.java files.
Updating activity_main.xml
Make following code into activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:hint="enter query" android:singleLine="true"> <requestFocus/> </EditText> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="15dp"/> </LinearLayout>
Updating MainActivity.java
Copy following into MainActivity.java
import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private Adapter adapter; private EditText etsearch; private String[] moviewList; public static ArrayList<Model> movieNamesArrayList; public static ArrayList<Model> array_sort; int textlength = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); moviewList = new String[]{"Xmen", "Titanic", "Captain America", "Iron man", "Rocky", "Transporter", "Lord of the rings", "The jungle book", "Tarzan","Cars","Shreck"}; recyclerView = (RecyclerView) findViewById(R.id.recycler); movieNamesArrayList = populateList(); Log.d("hjhjh", movieNamesArrayList.size() + ""); adapter = new Adapter(this,movieNamesArrayList); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false)); etsearch = (EditText) findViewById(R.id.editText); array_sort = new ArrayList<>(); array_sort = populateList(); recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new ClickListener() { @Override public void onClick(View view, int position) { Toast.makeText(MainActivity.this, array_sort.get(position).getName(), Toast.LENGTH_SHORT).show(); } @Override public void onLongClick(View view, int position) { } })); etsearch.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { textlength = etsearch.getText().length(); array_sort.clear(); for (int i = 0; i < movieNamesArrayList.size(); i++) { if (textlength <= movieNamesArrayList.get(i).getName().length()) { Log.d("ertyyy", movieNamesArrayList.get(i).getName().toLowerCase().trim()); if (movieNamesArrayList.get(i).getName().toLowerCase().trim().contains( etsearch.getText().toString().toLowerCase().trim())) { array_sort.add(movieNamesArrayList.get(i)); } } } adapter = new Adapter(MainActivity.this, array_sort); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false)); } }); } private ArrayList<Model> populateList(){ ArrayList<Model> list = new ArrayList<>(); for(int i = 0; i < 8; i++){ Model imageModel = new Model(); imageModel.setName(moviewList[i]); list.add(imageModel); } return list; } public interface ClickListener { void onClick(View view, int position); void onLongClick(View view, int position); } static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { private GestureDetector gestureDetector; private ClickListener clickListener; public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) { this.clickListener = clickListener; gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null) { clickListener.onLongClick(child, recyclerView.getChildPosition(child)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { clickListener.onClick(child, rv.getChildPosition(child)); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } } }
Share this tutorial with learners also.
Your sharing will help other in their path to android development.
Also you can use the comment section for any queries, reviews and suggestions.
So all for Android RecyclerView Search Filter tutorial.
Thank you.