RecyclerView Search/Filter and ItemClick

Read-only properties in JavaFX 8

RecyclerView Search/Filter and ItemClick







 

Android Custom RecyclerView Search/Filter and ItemClick.

Intro

Hello.Here is the thing :

  • RecyclerView with Custom CardViews.
  • CardViews are our viewItems and consist of images and text.
  • We can search/filter the custom recyclerview from a searchview.
  • Then we handle itemclicks of searched/filtered items getting their appropriate positions.

 

Screenshots

Here are the screenshots for the project:

All Items:

Filter Items Using SearchView:

Tools Used

  • IDE : Android Studio
  • Language: Java
  • OS : Windows 8

 

Code

Build.GradleData ObjectItemClickListenerMyHolder.javaMyAdapter.javaCustomFilter.javaMainActivity.javaContentMain.xmlModel.xmlVideo/DemoDownload
  • We need to use RecyclerView and CardView,so lets add appropriate dependencies.These two reside in support libraries.
apply plugin: 'com.android.application'
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    defaultConfig {
        applicationId "com.tutorials.hp.customrecyclerfiltering"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    compile 'com.android.support:cardview-v7:23.2.1'
    compile 'com.android.support:recyclerview-v7:23.2.1'
}
  • Soccer player objects.
  • This is our POJO, Plain Old Java Object. It defines each player, that is his name, playing position and image.
package com.tutorials.hp.customrecyclerfiltering;
/**
 * Created by Hp on 3/17/2016.
 */
public class Player {
    private String name;
    private String pos;
    private int img;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPos() {
        return pos;
    }
    public void setPos(String pos) {
        this.pos = pos;
    }
    public int getImg() {
        return img;
    }
    public void setImg(int img) {
        this.img = img;
    }
}
  • Our ItemClickListener interface.
  • Signature for our itemClick events. We'll be handling click events for our RecyclerView.
  • The onItemClick event will take a view object and its position.
package com.tutorials.hp.customrecyclerfiltering;
import android.view.View;
/**
 * Created by Hp on 3/17/2016.
 */
public interface ItemClickListener {
    void onItemClick(View v,int pos);
}
  • Our ViewHolder class.
  • Holds our imageviews and textviews for recycling.
  • We have two textviews and one imageview.
package com.tutorials.hp.customrecyclerfiltering;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
 * Created by Hp on 3/17/2016.
 */
public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    //OUR VIEWS
    ImageView img;
    TextView nameTxt,posTxt;
    ItemClickListener itemClickListener;
    public MyHolder(View itemView) {
        super(itemView);
        this.img= (ImageView) itemView.findViewById(R.id.playerImage);
        this.nameTxt= (TextView) itemView.findViewById(R.id.nameTxt);
        this.posTxt= (TextView) itemView.findViewById(R.id.posTxt);
        itemView.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        this.itemClickListener.onItemClick(v,getLayoutPosition());
    }
    public void setItemClickListener(ItemClickListener ic)
    {
        this.itemClickListener=ic;
    }
}
  • Our adapter class.
  • Subclasses RecyclerView.Adapter<VH>
  • Inflates Model layout
  • Binds data to our views.
  • Implements Filterable Interface
package com.tutorials.hp.customrecyclerfiltering;
import android.content.Context;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import java.util.ArrayList;
/**
 * Created by Hp on 3/17/2016.
 */
public class MyAdapter extends RecyclerView.Adapter<MyHolder> implements Filterable{
    Context c;
    ArrayList<Player> players,filterList;
    CustomFilter filter;
    public MyAdapter(Context ctx,ArrayList<Player> players)
    {
        this.c=ctx;
        this.players=players;
        this.filterList=players;
    }
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //CONVERT XML TO VIEW ONBJ
        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.posTxt.setText(players.get(position).getPos());
        holder.nameTxt.setText(players.get(position).getName());
        holder.img.setImageResource(players.get(position).getImg());
        //IMPLEMENT CLICK LISTENET
        holder.setItemClickListener(new ItemClickListener() {
            @Override
            public void onItemClick(View v, int pos) {
                Snackbar.make(v,players.get(pos).getName(),Snackbar.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;
    }
}
  • Our CustomFilter class.
  • Performs our filtering of data.
  • Subclass android.widget.Filter class
package com.tutorials.hp.customrecyclerfiltering;
import android.widget.Filter;
import java.util.ArrayList;
/**
 * Created by Hp on 3/17/2016.
 */
public class CustomFilter extends Filter{
    MyAdapter adapter;
    ArrayList<Player> filterList;
    public CustomFilter(ArrayList<Player> 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<Player> 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<Player>) results.values;
        //REFRESH
        adapter.notifyDataSetChanged();
    }
}
  • Our MainActivity class.
  • Is our Launcher activity.
  • Generates and passes dummy data to adapter.
  • Contains searchview where we handle onquerytext change event.
package com.tutorials.hp.customrecyclerfiltering;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
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.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
   SearchView sv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        sv= (SearchView) findViewById(R.id.mSearch);
        RecyclerView rv= (RecyclerView) findViewById(R.id.myRecycler);
        //SET ITS PROPETRIES
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setItemAnimator(new DefaultItemAnimator());
        //ADAPTER
        final MyAdapter adapter=new MyAdapter(this,getPlayers());
        rv.setAdapter(adapter);
        //SEARCH
        sv.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;
            }
        });
    }
    //ADD PLAYERS TO ARRAYLIST
    private ArrayList<Player> getPlayers()
    {
        ArrayList<Player> players=new ArrayList<>();
        Player p=new Player();
        p.setName("Ander Herera");
        p.setPos("Midfielder");
        p.setImg(R.drawable.herera);
        players.add(p);
        p=new Player();
        p.setName("David De Geaa");
        p.setPos("Goalkeeper");
        p.setImg(R.drawable.degea);
        players.add(p);
        p=new Player();
        p.setName("Michael Carrick");
        p.setPos("Midfielder");
        p.setImg(R.drawable.carrick);
        players.add(p);
        p=new Player();
        p.setName("Juan Mata");
        p.setPos("Playmaker");
        p.setImg(R.drawable.mata);
        players.add(p);
        p=new Player();
        p.setName("Diego Costa");
        p.setPos("Striker");
        p.setImg(R.drawable.costa);
        players.add(p);
        p=new Player();
        p.setName("Oscar");
        p.setPos("Playmaker");
        p.setImg(R.drawable.oscar);
        players.add(p);
        return players;
    }
}

 

  • Our main layout that shall get inflated into our activity's user interface.
  • Contains RecyclerView and Searchview.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.customrecyclerfiltering.MainActivity"
    tools:showIn="@layout/activity_main">
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">
        <android.support.v7.widget.SearchView
            android:id="@+id/mSearch"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            app:defaultQueryHint="Search.."
            ></android.support.v7.widget.SearchView>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/myRecycler"
            android:layout_width="wrap_content"
            android:layout_below="@+id/mSearch"
            android:layout_height="wrap_content"
            class="android.support.v7.widget.RecyclerView" />
    </LinearLayout>
</RelativeLayout>

 

  • Inflated to viewitem for our adapterview.
  • This is the model for a single CardView with image and two textviews. We'll be filtering these Cards.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_margin="5dp"
    card_view:cardCornerRadius="10dp"
    card_view:cardElevation="5dp"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/playerImage"
            android:padding="10dp"
            android:src="@drawable/herera" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Name"
            android:id="@+id/nameTxt"
            android:padding="10dp"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/playerImage" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Position"
            android:id="@+id/posTxt"
            android:padding="10dp"
            android:layout_alignBottom="@+id/playerImage"
            android:layout_alignParentRight="true" />
    </RelativeLayout>
</android.support.v7.widget.CardView>

  • We also have a video tutorial for this example explained in a step by step manner.
  • Moreover you can view the project demo there.
  • The full source code reference is of course in the link above.

Custom RecyclerView Cards -Search/Filter and OnItemClick [With Source Code]

 

- You can Download the full Project below. Source code is well commented.

Download

How to Run

  • Download the project above.
  • You'll get a zipped file,extract it.
  • Open the Android Studio.
  • Now close, already open project
  • From the Menu bar click on File >New> Import Project
  • Now Choose a Destination Folder, from where you want to import project.
  • Choose an Android Project.
  • Now Click on “OK“.
  • Done, your done importing the project,now edit it.

 

More

YouTube

  • Visit our channel for more examples like these.

Facebook

Oclemy,Cheers.

 

 

 

 



Rating :

Leave a Reply

Your email address will not be published. Required fields are marked *

2 × 4 =

COMMENTS