Tuesday, 19 July 2016

Android Filter RecyclerView Using SearchView In ToolBar

There might be requirement in your application where you want to implement the search functionality by having searchView widget inside the toolbar for filter the recyclerview . In the previous series of tutorial we have seen the basics of a recyclerView and it's scrolling behaviour and also on recyclerView with cardview , In this tutorial we will see the logic for filtering the items in  recyclerview .






Adding libraries

dependencies {
   
compile 'com.android.support:cardview-v7:24.0.0'
   
compile 'com.android.support:recyclerview-v7:24.0.0'
}
activity_main.xml
-------------------------
<?xml version="1.0" encoding="utf-8"?>
<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="com.example.anil.app1.MainActivity">

    <
android.support.v7.widget.RecyclerView
       
android:id="@+id/myrec"
       
android:layout_width="match_parent"
        
android:layout_height="match_parent"
       
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</
LinearLayout>
mycardview_xml
-----------------------------
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:card_view="http://schemas.android.com/apk/res-auto"
   
android:layout_width="match_parent"
   
android:layout_height="wrap_content"
   
android:orientation="horizontal"
   
card_view:cardCornerRadius="5dp"
   
card_view:cardElevation="3dp"
   
card_view:cardUseCompatPadding="true">

    <
RelativeLayout
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content">
        <
ImageView
           
android:id="@+id/list_avatar"
           
android:layout_width="40dp"
           
android:layout_height="40dp"
           
android:layout_alignParentLeft="true"
           
android:layout_centerVertical="true"
           
android:layout_marginLeft="10dp"
           
android:scaleType="centerCrop"
           
android:src="@drawable/settingicon" />

        <
TextView
           
android:id="@+id/list_title"
           
android:layout_width="match_parent"
           
android:layout_height="wrap_content"
           
android:layout_alignLeft="@+id/list_desc"
           
android:layout_alignParentTop="true"
           
android:layout_alignStart="@+id/list_desc"
           
android:text="Androidwarriors "
           
android:textAppearance="?attr/textAppearanceListItem"
           
android:textColor="#000000"
           
android:textSize="16sp" />

        <
TextView
           
android:id="@+id/list_desc"
           
android:layout_width="match_parent"
           
android:layout_height="wrap_content"
           
android:layout_below="@+id/list_title"
           
android:layout_marginLeft="16dp"
            
android:layout_toRightOf="@+id/list_avatar"
           
android:ellipsize="end"
           
android:singleLine="true"
           
android:text="Place to dive into android programming"
           
android:textAppearance="?attr/textAppearanceListItem"
           
android:textColor="#000000"
           
android:textSize="14sp" />
    </
RelativeLayout>
</
android.support.v7.widget.CardView>
Coding Part
----------------------------
Post.Java
package com.example.anil.app1;

/**
 * Created by Anil on 19-07-2016.
 */
public class Post {

   
private String postTitle;

   
private String postSubTitle;

   
public String getPostTitle() {
       
return postTitle;
    }

   
public void setPostTitle(String postTitle) {
       
this.postTitle = postTitle;
    }

   
public String getPostSubTitle() {
       
return postSubTitle;
    }

   
public void setPostSubTitle(String postSubTitle) {
       
this.postSubTitle = postSubTitle;
    }

   
public Post(String postTitle, String postSubTitle) {
       
this.postTitle = postTitle;
       
this.postSubTitle = postSubTitle;
    }
}
 MyRecAdapter.Java
---------------------------
package com.example.anil.app1;

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;
import java.util.List;

/**
 * Created by Anil on 19-07-2016.
 */
public class MyRecAdapter extends RecyclerView.Adapter<MyRecAdapter.VH> {
   
public List<Post> parkingList;

   
public Context context;
    ArrayList<Post>
mCountryModel;

   
public MyRecAdapter(List<Post> parkingList, Context context) {
       
this.parkingList = parkingList;
       
this.context = context;
    }


   
@Override
   
public MyRecAdapter.VH onCreateViewHolder(ViewGroup parent, int viewType) {
       
return new MyRecAdapter.VH(LayoutInflater.from(parent.getContext()).inflate(R.layout.mycardview, parent, false));
    }

   
@Override
   
public void onBindViewHolder(MyRecAdapter.VH holder, int position) {
        holder.
t1.setText(parkingList.get(position).getPostTitle());
        holder.
t2.setText(parkingList.get(position).getPostSubTitle());


    }

   
@Override
   
public int getItemCount() {
       
return parkingList.size();
    }

   
public class VH extends RecyclerView.ViewHolder {
        TextView
t1, t2;

       
public VH(View itemView) {
           
super(itemView);
           
t1 = (TextView) itemView.findViewById(R.id.list_title);
           
t2 = (TextView) itemView.findViewById(R.id.list_desc);
        }
    }

   
public void setFilter(List<Post> countryModels) {
       
mCountryModel = new ArrayList<>();
       
mCountryModel.addAll(countryModels);
        notifyDataSetChanged();
    }
}
 MainActivity.Java
---------------------------
package com.example.anil.app1;

import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
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 android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
    MyRecAdapter
myRecAdapter;
    RecyclerView
recyclerView;
    List<Post>
list;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
       
recyclerView = (RecyclerView) findViewById(R.id.myrec);
        createdata();
       
myRecAdapter = new MyRecAdapter(list, MainActivity.this);
       
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
       
recyclerView.setAdapter(myRecAdapter);

    }

   
void createdata() {
//        myRecAdapter.notifyDataSetChanged();
       
list = new ArrayList<>();
       
list.add(new Post("Anil", "Tadipatri,RaylaSeema"));
       
list.add(new Post("Aswartha", "Jammalamadugu,RaylaSeema"));
       
list.add(new Post("Jayachandra", "Konnali,RaylaSeema"));
       
list.add(new Post("Mohan", "Pileru,RaylaSeema"));
       
list.add(new Post("TulasiRam", "Pulivendula,RaylaSeema"));
       
list.add(new Post("Ashraff", "Rayachoti,RaylaSeema"));
       
list.add(new Post("Kishore", "Rajampeta,RaylaSeema"));
       
list.add(new Post("Mahendra", "Porumamilla,RaylaSeema"));
       
list.add(new Post("Veera", "Ananthapur,RaylaSeema"));
    }

   
@Override
   
public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.
menu_search, menu);

        MenuItem item = menu.findItem(R.id.
search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);

        searchView.setOnQueryTextListener(
this);

       
return super.onCreateOptionsMenu(menu);
    }


   
@Override
   
public boolean onQueryTextSubmit(String query) {
//        Toast.makeText(MainActivity.this, "Name is : "+query, Toast.LENGTH_SHORT).show();
       
return false;
    }

   
@Override
   
public boolean onQueryTextChange(String newText) {

       
final List<Post> filteredModelList = filter(list, newText);
       
if (filteredModelList.size() > 0) {
           
myRecAdapter.setFilter(filteredModelList);
           
return true;
        }
else {
            Toast.makeText(MainActivity.
this, "Not Found", Toast.LENGTH_SHORT).show();
           
return false;
        }
    }

   
private List<Post> filter(List<Post> models, String query) {
        query = query.toLowerCase();

       
final List<Post> filteredModelList = new ArrayList<>();
       
for (Post model : models) {
           
final String text = model.getPostTitle().toLowerCase();
           
if (text.contains(query)) {
                filteredModelList.add(model);

            }
        }
        createdata();
       
myRecAdapter = new MyRecAdapter(filteredModelList, MainActivity.this);
       
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
       
recyclerView.setAdapter(myRecAdapter);
       
myRecAdapter.notifyDataSetChanged();
       
return filteredModelList;
    }
}



9 comments:

  1. whers..s your example download

    ReplyDelete
  2. really if you want give me your email id i will send it

    ReplyDelete
  3. Very nice and helpful tutorial, thank you
    Can you please send me the source code at: asifiqbal.iqbal19@gmail.com

    ReplyDelete
  4. Nice, Thank You...

    ReplyDelete
  5. Hi I tried your exact code on my project and it keeps crashing. Can you help me ?

    ReplyDelete
    Replies
    1. I can send you my project file if you might have the time to look at it

      Delete
  6. code pls
    sathyamoorthyme@gmail.com

    ReplyDelete
  7. Sir please can u help me..im stucked on this since long sir if u provide me ur email id i can email u my code...my doubt is :
    how to maintain the position of items in recyclerview when a search filter has been implemented?

    well the scenario is that when I search for item D which is in the 4 position the intent activity that is for item D became item A intent which is not what i want.

    What i want is if I search for item D the activity for item D remains the same.

    ReplyDelete