Android Custom Filter/Search ListView With Images Text [BaseAdapter]

| Page Views: 13512

Android Custom ListView with Images and Text Search Filter

How to search filter a custom ListView with images and text using a searchview. Our adapter is BaseAdapter.

1. Introduction

Searching data is one of the most basic of requirements when it comes to computing. The biggest advantage of computer is it's speed and ability to handle large volumes of data. Through data mining techniques computers can tell us usable patterns from data.

However in day to day in our android app we also need to provide our users with the ability to search data. Users can only view about 5 to 10 items per screen. Thus even if you have say a hundred items, you need to give users the ability to filter that data down to what he/she needs.

This can easily be done via a searchview. And this type of filtering is the purpose of this tutorial.

(a). Demo

Let's start by looking at the demo of what we create in this class.

(b). Tools used

Here are the Tools I used in creating this project. Note they may be abit old school as newer tools like Android Studio come in place.

Type Tool
LANGUAGE Java
PLATFORM Android
IDE Eclipse
EMULATOR Bluestacks

2. Java Code

Let's write code. No third party library is needed.

(a). Player.java

Purpose :

  1. Is our POJO class.Plain Old Java Object
  2. Holds data consisting of a single Player.

So basically our ListView will comprise of footbal players. Each Player has a name and an image.

package com.tutorials.listviewcustomfilterbase;

public class Player {

  private String name;
  private int img;

  public Player(String name,int img) {
    this.name=name;
    this.img=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;
  }
}
(b). CustomAdapter.java

Purpose:

  1. Adapts our images and Text to our ListView
  2. Is where we bind data to views
  3. Has an inner class CustomFilter that implements Filtering or Searching for us.
  4. Implements Filterable method hence we override getFilter() method that in turn returns a filter object.
package com.tutorials.listviewcustomfilterbase;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

public class Adapter extends BaseAdapter implements Filterable{

  Context c;
  ArrayList<Player> players;
  CustomFilter filter;
  ArrayList<Player> filterList;

  public Adapter(Context ctx,ArrayList<Player> players) {
    // TODO Auto-generated constructor stub

    this.c=ctx;
    this.players=players;
    this.filterList=players;
  }

  @Override
  public int getCount() {
    // TODO Auto-generated method stub
    return players.size();
  }

  @Override
  public Object getItem(int pos) {
    // TODO Auto-generated method stub
    return players.get(pos);
  }

  @Override
  public long getItemId(int pos) {
    // TODO Auto-generated method stub
    return players.indexOf(getItem(pos));
  }

  @Override
  public View getView(int pos, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    LayoutInflater inflater=(LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if(convertView==null)
    {
      convertView=inflater.inflate(R.layout.model, null);
    }

    TextView nameTxt=(TextView) convertView.findViewById(R.id.nameTv);
    ImageView img=(ImageView) convertView.findViewById(R.id.imageView1);

    //SET DATA TO THEM
    nameTxt.setText(players.get(pos).getName());
    img.setImageResource(players.get(pos).getImg());

    return convertView;
  }

  @Override
  public Filter getFilter() {
    // TODO Auto-generated method stub
    if(filter == null)
    {
      filter=new CustomFilter();
    }

    return filter;
  }

  //INNER CLASS
  class CustomFilter extends Filter
  {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
      // TODO Auto-generated method stub

      FilterResults results=new FilterResults();

      if(constraint != null && constraint.length()>0)
      {
        //CONSTARINT TO UPPER
        constraint=constraint.toString().toUpperCase();

        ArrayList<Player> filters=new ArrayList<Player>();

        //get specific items
        for(int i=0;i<filterList.size();i++)
        {
          if(filterList.get(i).getName().toUpperCase().contains(constraint))
          {
            Player p=new Player(filterList.get(i).getName(), filterList.get(i).getImg());

            filters.add(p);
          }
        }

        results.count=filters.size();
        results.values=filters;

      }else
      {
        results.count=filterList.size();
        results.values=filterList;

      }

      return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
      // TODO Auto-generated method stub

      players=(ArrayList<Player>) results.values;
      notifyDataSetChanged();
    }

  }

}
(c). Our MainActivity class

Purpose :

  1. Our launcher activity
  2. We set reference our ListView from XML and attach its BaseAdapter subclass to it.
  3. We reference our SearchView and implement its onQueryTextChangeListener.
package com.tutorials.listviewcustomfilterbase;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;

public class MainActivity extends Activity {

  ListView lv;
  SearchView sv;

  String[] names={"Juan Mata","Ander Herera","Wayne Rooney","Eden Hazard","Michael Carrick","Diego Costa","Jose Mourinho"};
  int[] images={R.drawable.mata,R.drawable.herera,R.drawable.rooney,R.drawable.hazard,R.drawable.carrick,R.drawable.costa,R.drawable.mourinho};

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

        lv=(ListView) findViewById(R.id.listView1);
        sv=(SearchView) findViewById(R.id.searchView1);

        //ADASPTER
        final Adapter adapter=new Adapter(this, getPlayers());
        lv.setAdapter(adapter);

        sv.setOnQueryTextListener(new OnQueryTextListener() {

      @Override
      public boolean onQueryTextSubmit(String arg0) {
        // TODO Auto-generated method stub
        return false;
      }

      @Override
      public boolean onQueryTextChange(String query) {
        // TODO Auto-generated method stub

        adapter.getFilter().filter(query);

        return false;
      }
    });

    }

    private ArrayList<Player> getPlayers()
    {
        ArrayList<Player> players=new ArrayList<Player>();
        Player p;

        for(int i=0;i<names.length;i++)
        {
            p=new Player(names[i], images[i]);
            players.add(p);
        }

        return players;
    }

}

3. Layouts

(a). Our activity_main.xml layout

Purpose :

  1. Acts as our template Layout.
  2. Hold our ListView and SearchView
<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"
    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" >

    <SearchView
        android:id="@+id/searchView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignRight="@+id/listView1"
        android:layout_marginLeft="14dp"
        android:queryHint="Search.." >

    </SearchView>

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/searchView1" >

    </ListView>

</RelativeLayout>
(b). Our Model.xml Layout

Purpose :

  1. Acts as our Row Model.Remember we want to display Listview with images and text.So its how a single row in our ListView shall appear.
  2. Contains Images andText.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="44dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/nameTv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/imageView1"
        android:layout_toRightOf="@+id/imageView1"
        android:text="Name"
        android:padding="10dp"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

Good day.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section.

About Me.

After completing his Software Engineering bachelors program, Oclemy(Clement Ochieng) these days is a man of two lives. At day he works for a startup in Nairobi, Kenya. At night he works tirelessly on building ProgrammingWizards TV, a tv channel for student coders and this website to help share the source code. In between he practices Meditation and Self actualization to help him keep balance. He also likes going for long solo walks to connect more with nature.




Recommendations


What do You Think


Previous Post Next Post