Android Filter Recyclerview by using SearchView in ToolBar or actionbar

In this tutorial we will cover the following:
Recyclerview
CardView
Custom Row
SearchView
Row Animation
Item Click

Step 01: Add following dependencies in build.gradle(Module:app) under dependencies{}

implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'com.android.support:recyclerview-v7:27.1.0'

Step 02: Create menu.xml under res>menu folder, to search item.

<?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"
  xmlns:tools="http://schemas.android.com/tools"
  tools:context=".MainActivity">

   <item android:id="@+id/action_search" 
    android:title="Search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    android:icon="@drawable/search"
    app:searchHintIcon="@drawable/search"
    app:showAsAction="always|collapseActionView" />
</menu>

Step 03: Create model.xml in res>layout folder, to design row

<?xml version="1.0" encoding="utf-8"?>
<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"
    card_view:cardUseCompatPadding="true"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="5dp"
    card_view:cardBackgroundColor="@color/colorWhite">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/playerImage"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher_round"/>

        <TextView
            android:id="@+id/nameTxt"
            android:layout_toRightOf="@id/playerImage"
            android:layout_toEndOf="@id/playerImage"
            android:layout_centerVertical="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="Name"
            android:textColor="@color/colorBlack" />
    </RelativeLayout>

</android.support.v7.widget.CardView>

Step 04: Add new colors White and Black in res>values>colors

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorWhite">#fff</color>
    <color name="colorBlack">#000</color>
</resources>

Step 05: activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/myRecycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />

</RelativeLayout>

Step 06: Create a class "Model.java"

package com.blogspot.devofandroid.myapplication;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */

public class Model {
    private String name;
    private int img;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getImg() {
        return img;
    }
    public void setImg(int img) {
        this.img = img;
    }
}

Step 07: Create a new Class "MyHolder.java"

package com.blogspot.devofandroid.myapplication;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */
public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    //OUR VIEWS
    ImageView img;
    TextView nameTxt;
    ItemClickListener itemClickListener;
    public MyHolder(View itemView) {
        super(itemView);
        this.img= (ImageView) itemView.findViewById(R.id.playerImage);
        this.nameTxt= (TextView) itemView.findViewById(R.id.nameTxt);
        itemView.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        this.itemClickListener.onItemClick(v,getLayoutPosition());
    }
    public void setItemClickListener(ItemClickListener ic)
    {
        this.itemClickListener=ic;
    }
}

Step 08: Create a new Class "MyAdapter.java"

package com.blogspot.devofandroid.myapplication;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.Toast;
import java.util.ArrayList;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */

public class MyAdapter extends RecyclerView.Adapter<MyHolder> implements Filterable {
    Context c;
    ArrayList<Model> players,filterList;
    CustomFilter filter;
    public MyAdapter(Context ctx,ArrayList<Model> players)
    {
        this.c=ctx;
        this.players=players;
        this.filterList=players;
    }
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //CONVERT XML TO VIEW OBJ
        View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model,null);
        //HOLDER
        MyHolder holder = new MyHolder(v);
        return holder;
    }
    //DATA BOUND TO VIEWS
    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        //BIND DATA
        holder.nameTxt.setText(players.get(position).getName());
        holder.img.setImageResource(players.get(position).getImg());

        Animation animation = AnimationUtils.loadAnimation(c, android.R.anim.slide_in_left);
        holder.itemView.startAnimation(animation);

        //IMPLEMENT CLICK LISTENER
        holder.setItemClickListener(new ItemClickListener() {
            @Override
            public void onItemClick(View v, int pos) {

                if (players.get(pos).getName().equals("Home")){
                    Toast.makeText(c, "Home...", Toast.LENGTH_SHORT).show();
                }
                else if (players.get(pos).getName().equals("Contacts")){
                    Toast.makeText(c, "Contacts...", Toast.LENGTH_SHORT).show();
                }
                else if (players.get(pos).getName().equals("Images")){
                    Toast.makeText(c, "Images...", Toast.LENGTH_SHORT).show();
                }
                else if (players.get(pos).getName().equals("Videos")){
                    Toast.makeText(c, "Videos...", Toast.LENGTH_SHORT).show();
                }
                else if (players.get(pos).getName().equals("Mails")){
                    Toast.makeText(c, "Mails...", Toast.LENGTH_SHORT).show();
                }

            }
        });
    }
    //GET TOTAL NUM OF PLAYERS
    @Override
    public int getItemCount() {
        return players.size();
    }
    //RETURN FILTER OBJ
    @Override
    public Filter getFilter() {
        if(filter==null)
        {
            filter=new CustomFilter(filterList,this);
        }
        return filter;
    }
}

Step 09: Create a new Class "CustomFilter.java"

package com.blogspot.devofandroid.myapplication;

import android.widget.Filter;
import java.util.ArrayList;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */

public class CustomFilter extends Filter{
    MyAdapter adapter;
    ArrayList<Model> filterList;
    public CustomFilter(ArrayList<Model> filterList, MyAdapter adapter)
    {
        this.adapter=adapter;
        this.filterList=filterList;
    }
    //FILTERING OCURS
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults results=new FilterResults();
        //CHECK CONSTRAINT VALIDITY
        if(constraint != null && constraint.length() > 0)
        {
            //CHANGE TO UPPER
            constraint=constraint.toString().toUpperCase();
            //STORE OUR FILTERED PLAYERS
            ArrayList<Model> filteredPlayers=new ArrayList<>();
            for (int i=0;i<filterList.size();i++)
            {
                //CHECK
                if(filterList.get(i).getName().toUpperCase().contains(constraint))
                {
                    //ADD PLAYER TO FILTERED PLAYERS
                    filteredPlayers.add(filterList.get(i));
                }
            }
            results.count=filteredPlayers.size();
            results.values=filteredPlayers;
        }else
        {
            results.count=filterList.size();
            results.values=filterList;
        }
        return results;
    }
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        adapter.players= (ArrayList<Model>) results.values;
        //REFRESH
        adapter.notifyDataSetChanged();
    }
}

Step 10: Create a new Interface "ItemClickListener.java"

package com.blogspot.devofandroid.myapplication;

import android.view.View;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */

public interface ItemClickListener {
    void onItemClick(View v, int pos);
}

Step 11: MainActivity.java

package com.blogspot.devofandroid.myapplication;

import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
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 java.util.ArrayList;

/**
 * Created by Atif on 11/3/2018.
 * devofandroid.blogspot.com
 */

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";


    private RecyclerView rv;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //sv= (SearchView) findViewById(R.id.mSearch);
        rv= (RecyclerView) findViewById(R.id.myRecycler);
        //SET ITS PROPERTIES
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setItemAnimator(new DefaultItemAnimator());
        //ADAPTER
        adapter=new MyAdapter(this,getPlayers());
        rv.setAdapter(adapter);

    }


    //ADD PLAYERS TO ARRAYLIST
    private ArrayList<Model> getPlayers() {
        ArrayList<Model> players=new ArrayList<>();
        Model p=new Model();
        p.setName("Home");
        p.setImg(R.drawable.home);
        players.add(p);

        p=new Model();
        p.setName("Contacts");
        p.setImg(R.drawable.contact);
        players.add(p);

        p=new Model();
        p.setName("Images");
        p.setImg(R.drawable.images);
        players.add(p);

        p=new Model();
        p.setName("Videos");
        p.setImg(R.drawable.videos);
        players.add(p);

        p=new Model();
        p.setName("Mails");
        p.setImg(R.drawable.mail);
        players.add(p);

        return players;

    }

    @Override
    public boolean onCreateOptionsMenu( Menu menu) {
        getMenuInflater().inflate( R.menu.menu, menu);
        final MenuItem item = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }
            @Override
            public boolean onQueryTextChange(String query) {
                //FILTER AS YOU TYPE
                adapter.getFilter().filter(query);
                return false;
            }
        });
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement

        return true;
    }

}

Step 12: Output

Android Filter Recyclerview by using SearchView in ToolBar or actionbar
 Android Filter Recyclerview by using SearchView in ToolBar or actionbarAndroid Filter Recyclerview by using SearchView in ToolBar or actionbar


Comments

Popular posts from this blog

Picture In Picture | Android Studio | Kotlin

Manage External Storage Permission | Android Studio | Kotlin

How to add AIDL folder | Android Studio