Search code examples
androidlistcustom-adaptercustom-lists

Unable to implement search feature on a custom list view


I am making a custom listView and i take a edit text on the top of list view to search the items in list view but when i enter any value in edit text it search in list view but when i clear the edit test it does not show the original list view
my main activity code is

package com.example.searchonlist;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.ListView;

public class MainActivity extends Activity implements TextWatcher  {

	private FriendListAdapter friendListAdapter;
	private EditText inputSearch;
	private ListView friendList;
	private ArrayList<String> frndArrList;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		inputSearch = (EditText) findViewById(R.id.inputSearch);
		inputSearch.addTextChangedListener(this);

		frndArrList = new ArrayList<String>();
		frndArrList.add("Ashutosh");
		frndArrList.add("ShreeVridhee");
		frndArrList.add("Tanishi");
		frndArrList.add("Divyanu");
		frndArrList.add("Adarsh");
		frndArrList.add("Akshara");
		frndArrList.add("Pooja");
		frndArrList.add("NoOne");

		friendList = (ListView) findViewById(R.id.listView1);
		friendListAdapter = new FriendListAdapter(this, frndArrList);
		friendList.setAdapter(friendListAdapter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {

	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {

		Log.e("EditText", s.toString());

		friendListAdapter.getFilter().filter(s.toString());

	}

	@Override
	public void afterTextChanged(Editable s) {

	}
	
	@Override
	public void onBackPressed() {
		super.onBackPressed();
    }

}

and my list adapter is

package com.example.searchonlist;

import java.util.ArrayList;

import android.util.Log;
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.TextView;

public class FriendListAdapter extends BaseAdapter implements Filterable {
	MainActivity context;
	ArrayList<String> frndArrList;
	ArrayList<String> filterArrList;
	private FriendFilter friendFilter;

	public FriendListAdapter(MainActivity context, ArrayList<String> frndArrList) {
		this.context = context;
		this.frndArrList = frndArrList;
		this.filterArrList = frndArrList;
	}

	@Override
	public int getCount() {

		return frndArrList.size();
	}

	@Override
	public Object getItem(int position) {

		return position;
	}

	@Override
	public long getItemId(int position) {

		return position;
	}

	@Override
	public View getView(int position, View view, ViewGroup parent) {

		LayoutInflater layoutInflater = LayoutInflater.from(context);
		view = layoutInflater.inflate(R.layout.inflate_view, parent, false);
		TextView txtView = (TextView) view.findViewById(R.id.inflate_txtView);
		txtView.setText(frndArrList.get(position));

		return view;
	}

	@Override
	public Filter getFilter() {
		if (friendFilter == null)
			friendFilter = new FriendFilter();

		return friendFilter;

	}

	private class FriendFilter extends Filter {

		@Override
		protected FilterResults performFiltering(CharSequence constraint) {
			  FilterResults results = new FilterResults();
			  
			  if (constraint == null || constraint.length() == 0) {
			        // No filter implemented we return all the list
				  
			        results.values = frndArrList;
			        results.count = frndArrList.size();
			    }
			
			  else {
			        // We perform filtering operation
			        ArrayList<String> nPlanetList = new ArrayList<String>();
			        for (String p : frndArrList) {
			        	Log.v("String", p);
			            if (p.toLowerCase().contains(constraint.toString().toLowerCase()))
			                nPlanetList.add(p);
			            Log.e("nPlanetList", nPlanetList.toString());
			        }
			         
			        results.values = nPlanetList;
			        results.count = nPlanetList.size();
			 
			    }
			return results;
			
		}

		@Override
		protected void publishResults(CharSequence constraint,
				FilterResults results) 
		        {
			        frndArrList = (ArrayList<String>) results.values;
			        notifyDataSetChanged();
			    }
			

		}

	}


Solution

  • This is happening because of your publishResults method. You are assigning frndArrList to be the results of your search, which means after you input a search, you actually remove all references to the data that was in your origin array list. To fix this, you need to change the following:

    public int getCount() {
        return filterArrList.size()
    }
    
    //...
    
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        view = layoutInflater.inflate(R.layout.inflate_view, parent, false);
        TextView txtView = (TextView) view.findViewById(R.id.inflate_txtView);
        //txtView.setText(frndArrList.get(position));
        txtView.setText(filterArrList.get(position));
    
        return view;
    }
    
    //...
    
    protected void publishResults(CharSequence constraint,
                FilterResults results) 
                {
                    filterArrList= (ArrayList<String>) results.values;
                    notifyDataSetChanged();
                }
        }