Android S1E19 : RecyclerView – ToolBar Search/Filter

Android S1E19 : RecyclerView – ToolBar Search/Filter







Android RecyclerView MaterialSearchBar Search Filter

Introduction

We had done a tutorial some months later about Search/Filter with recyclerView. However, that was with the searchview as our search form. Today we see how to search filter with material searchbar as the search component. User will perform realtime search filter. As they type we filter the cards based on the search term. Our recyclerview comprises of material cardviews. We populate our recyclerview via an arraylist of strings.

Let's go.

Screenshot

  • Here's the screenshot of the project.

Android RecyclerView Material Seatchbar Search Filter.

SearchBar RecyclerView

Android Material SearchBar RecyclerView example. : Project Structure.

Project Structure

Common Questions this example explores

  • Android RecyclerView Search/Filter with searchbar.
  • Android toolbar search filter.
  • Search filter recyclerview cardviews.
  • Android material searchbar recyclerview.

Tools Used

This example was written with the following tools:

  • Windows 8
  • AndroidStudio IDE
  • Genymotion Emulator
  • Language : Java
  • Topic : RecyclerView Events, Android SimpleRecyclerView

Libaries Used

  • We use Android SimpleRecyclerView library.

Source Code

Lets jump directly to the source code.

Build.Gradle Project LevelBuild.Gradle App LevelMyAdapter.javaFilterHelper.javaMainActivity.javaactivity_main.xmlcontent_main.xmlmodel.xmlVideo TutorialDownload
  • Our project level build.gradle.
  • We add repositories for fetching our dependencies here.
  • The dafult,jccenter() is already specified.
  • However, we add the maven and specify the url we'll use to fetch our third part library here.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
//add maven jitpack.io for fetching our materialsearchbar library.
allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

 

  • Our module level build.gradle file.
  • We specify compilesdk,minimum sdk,target sdk and dependencies.
  • Note that the minimum sdk for this project is API level 16 as the material serahbar library we use requires that.
  • We also add dependencies using 'compile' statement.
  • Our activity shall derive from the appCompatActivity to make it target earlier android versions.
  • We also specify design support library as well as CardView.
  • Add dependencies including com.github.mancj:MaterialSearchBar:0.7.1.
  • This is the material searchbar we will use in our project.
apply plugin: 'com.android.application'
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.tutorials.hp.searchbarrecyclerview"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
//Add our dependencies including materialsearchbar
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support:design:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
    compile 'com.android.support:cardview-v7:26.+'
    compile 'com.github.mancj:MaterialSearchBar:0.7.1'
}

 

  • Our MyAdapter class.
  • Derives from RecyclerView.Adapter.
  • Implements android.widget.filterable interface.
  • We include our MyViewHolder as an inner class.
  • This adapter layout will be responsible inflating model layout and binding data to resulting views.
package com.tutorials.hp.searchbarrecyclerview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements Filterable {
    ArrayList<String> galaxies;
    ArrayList<String> currentList;
    public MyAdapter(ArrayList<String> galaxies) {
        this.galaxies = galaxies;
        this.currentList=galaxies;
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model,parent,false);
        return new MyViewHolder(v);
    }
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.nametxt.setText(galaxies.get(position));
    }
    @Override
    public int getItemCount() {
        return galaxies.size();
    }
    public void setGalaxies(ArrayList<String> filteredGalaxies)
    {
        this.galaxies=filteredGalaxies;
    }
    @Override
    public Filter getFilter() {
        return FilterHelper.newInstance(currentList,this);
    }
    /*
    - Our MyViewHolder class
     */
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView nametxt;
        public MyViewHolder(View itemView) {
            super(itemView);
            nametxt= itemView.findViewById(R.id.nameTxt);
        }
    }
}

 

  • Our FilterHelper class.
  • Derives from android.widget.filter.
  • We perform filtering here and publish results back to the adapter which is then refreshed.
package com.tutorials.hp.searchbarrecyclerview;
import android.widget.Filter;
import java.util.ArrayList;
public class FilterHelper extends Filter {
    static ArrayList<String> currentList;
    static MyAdapter adapter;
    public static FilterHelper newInstance(ArrayList<String> currentList, MyAdapter adapter) {
        FilterHelper.adapter=adapter;
        FilterHelper.currentList=currentList;
        return new FilterHelper();
    }
    /*
    - Perform actual filtering.
     */
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults filterResults=new FilterResults();
        if(constraint != null && constraint.length()>0)
        {
            //CHANGE TO UPPER
            constraint=constraint.toString().toUpperCase();
            //HOLD FILTERS WE FIND
            ArrayList<String> foundFilters=new ArrayList<>();
            String galaxy;
            //ITERATE CURRENT LIST
            for (int i=0;i<currentList.size();i++)
            {
                galaxy= currentList.get(i);
                //SEARCH
                if(galaxy.toUpperCase().contains(constraint))
                {
                    //ADD IF FOUND
                    foundFilters.add(galaxy);
                }
            }
            //SET RESULTS TO FILTER LIST
            filterResults.count=foundFilters.size();
            filterResults.values=foundFilters;
        }else
        {
            //NO ITEM FOUND.LIST REMAINS INTACT
            filterResults.count=currentList.size();
            filterResults.values=currentList;
        }
        //RETURN RESULTS
        return filterResults;
    }
    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        adapter.setGalaxies((ArrayList<String>) filterResults.values);
        adapter.notifyDataSetChanged();
    }
}

 

  • Our MainActivity class.
  • Derives from AppCompatActivity which is a Base class for activities that use the support library action bar features.
  • Methods: onCreate(),getData().
  • Inflated From activity_main.xml using the setContentView() method.
  • The views we use are RecyclerView.
  • Reference RecyclerView from our layout specification using findViewById().
  • getData() will be our data source.
package com.tutorials.hp.searchbarrecyclerview;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import com.mancj.materialsearchbar.MaterialSearchBar;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
    RecyclerView rv;
    MyAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //RFERENCE VIEWS
        rv= (RecyclerView) findViewById(R.id.mRecyclerView);
        rv.setLayoutManager(new LinearLayoutManager(this));
        MaterialSearchBar searchBar = (MaterialSearchBar) findViewById(R.id.searchBar);
        searchBar.setHint("Search..");
        searchBar.setSpeechMode(true);
        //ADAPTER
        adapter=new MyAdapter(getGalaxies());
        rv.setAdapter(adapter);
        //SEARCHBAR TEXT CHANGE LISTENER
        searchBar.addTextChangeListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //SEARCH FILTER
                adapter.getFilter().filter(charSequence);
            }
            @Override
            public void afterTextChanged(Editable editable) {
            }
        });
    }
    private ArrayList<String> getGalaxies()
    {
        ArrayList<String> galaxies=new ArrayList<>();
        galaxies.add("Cartwheel");
        galaxies.add("Whirlpool");
        galaxies.add("Andromeda I");
        galaxies.add("Andromeda II");
        galaxies.add("Sombrero");
        galaxies.add("Messier 81");
        galaxies.add("Messier 87");
        galaxies.add("Canis Majos Over-density");
        galaxies.add("Messier 92");
        galaxies.add("Black Eye");
        galaxies.add("Centaurus A");
        galaxies.add("Centaurus B");
        galaxies.add("Milky Way");
        galaxies.add("IC 1011");
        galaxies.add("Star Bust");
        galaxies.add("Hoag's Object");
        galaxies.add("Pinwheel");
        galaxies.add("Triangulum");
        galaxies.add("Cosmos Redshift");
        galaxies.add("Ursa Minor");
        galaxies.add("Virgo Stellar-Stream");
        return galaxies;
    }
}

 

  • Our activity_main.xml layout
  • Will be inflated to our mainactivity.
  • Add MaterialSearchBar in the appbar.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context="com.tutorials.hp.searchbarrecyclerview.MainActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
        <com.mancj.materialsearchbar.MaterialSearchBar
            app:theme="@style/AppTheme.PopupOverlay"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/searchBar" />
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_main" />
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

 

  • Add recyclerview here.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.searchbarrecyclerview.MainActivity"
    tools:showIn="@layout/activity_main">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/mRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>

 

  • As the name suggests, this layout models our viewitem.
  • We define how each Card shall appear in our List.
  • So at the root level we have a CardView widget.
  • We can also customize our CardView by specifying cardCornerRadius,cardElevation,width,height etc.
  • Each Card shall comprise a textview.
<?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="15dp"
    card_view:cardElevation="10dp"
    android:layout_height="150dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Galaxy"
            android:id="@+id/nameTxt"
            android:padding="10dp"
      android:textColor="@color/abc_btn_colored_borderless_text_material"
            android:layout_alignParentLeft="true"/>
</android.support.v7.widget.CardView>

 

  • We have a YouTube channel with almost a thousand tutorials, this one below being one of them.

Android S1E19 : RecyclerView - ToolBar Search/Filter

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

How To Run

  1. Download the project above.
  2. You'll get a zipped file,extract it.
  3. Open the Android Studio.
  4. Now close, already open project.
  5. From the Menu bar click on File >New> Import Project.
  6. Now Choose a Destination Folder, from where you want to import project.
  7. Choose an Android Project.
  8. Now Click on “OK“.
  9. 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 *

    13 + seventeen =

    COMMENTS