Search code examples
androidsearchfilterandroid-recyclerviewandroid-adapter

Android - Implementing search filter to a RecyclerView


I need to implement a search feature based on an EditText to my RecyclerView. The list must be filtered while typing.

Here's the code :

DisplayAdapter.java this is the adapter

public class DisplayAdapter extends RecyclerView.Adapter<DisplayAdapter.MyViewHolder>{
    private List<DataHolder> displayedList;
    public class MyViewHolder extends RecyclerView.ViewHolder{
        public TextView english_d;
        public MyViewHolder(View view){
              super(view);
              english_d = (TextView) view.findViewById(R.id.engword);
        }
   }
    public DisplayAdapter(List<DataHolder> displayedList){
        this.displayedList = displayedList;
      }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int position)    {
    // create a layout
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);

    return new  MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    DataHolder content = displayedList.get(position);
    holder.english_d.setText(content.getEnglish());
   }
@Override
public int getItemCount() {
    return displayedList.size();
   }
}

DataHolder.java

public class DataHolder {
private String english;


public DataHolder() {
}

public DataHolder(String english, String german) {
    this.english = english;
   
}

public String getEnglish() {
    return english;
}

public void setEnglish(String english) {
    this.english = english;
   }

}

and here's the Fragment that I am working with :

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_two_fragment, container, false);

        rv = (RecyclerView) view.findViewById(R.id.list_view_english);
        rv.setHasFixedSize(true);
       
        inputSearch = (EditText) view.findViewById(R.id.inputSearch);
        
        rv.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
        final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        rv.setLayoutManager(layoutManager);

        
        DisplayContent();
        

        disp_adapter = new DisplayAdapter(displayedList);
        
        rv.setAdapter(disp_adapter);
   return view;
}

Solution

  • in your adapter add new function for update the list

    public void updateList(List<DataHolder> list){
         displayedList = list;
         notifyDataSetChanged();
    }
    

    add textWatcher for search lets say you are using Edittext as search field

    searchField.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                // TODO Auto-generated method stub
            }
    
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                // TODO Auto-generated method stub
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
                // filter your list from your input
                filter(s.toString());
                //you can use runnable postDelayed like 500 ms to delay search text
            }
        });
    

    Simple filter function

    void filter(String text){
         List<DataHolder> temp = new ArrayList();
         for(DataHolder d: displayedList){
               //or use .equal(text) with you want equal match
               //use .toLowerCase() for better matches
               if(d.getEnglish().contains(text)){
                   temp.add(d);
               }
         }
         //update recyclerview
         disp_adapter.updateList(temp);
    }
    


    With Butterknife

    @OnTextChanged(R.id.feature_manager_search)
    protected void onTextChanged(CharSequence text) {
        filter(text.toString());
    }