androidandroid-recyclerviewandroid-sqliteandroid-search

How to fix/implement Search Filter with RecyclerView


I followed the same youtube tutorial (https://www.youtube.com/watch?v=VQKq9RHMS_0&ab_channel=Stevdza-San) and read the answer/feedback from this user's question (How to implement Search Filter with RecyclerView).

I want to add the Search Bar and have the results be filtered but am struggling with it. Even the tutorials like the User came across are not helping as I am having the same issue. I really hope someone can help me, I really would be grateful.

MainActivity.java

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

    getSupportActionBar().setTitle("Items List Screen");


    recyclerViewItem = findViewById(R.id.recyclerViewItem);
    add_i_button = (FloatingActionButton) findViewById(R.id.add_i_button);
    refresh_item_button = (FloatingActionButton) findViewById(R.id.refresh_item_button);
    empty_imageviewitem = findViewById(R.id.empty_imageviewitem);
    no_dataitem = findViewById(R.id.no_dataitem);
    add_i_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(ItemListScreen.this, AddItemActivity.class));

        }
    });

    refresh_item_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            finish();
            startActivity(new Intent(ItemListScreen.this, ItemListScreen.class));
        }
    });

    myDB = new MyItemDatabaseHelper(ItemListScreen.this);
    item_id = new ArrayList<>();
    item_title = new ArrayList<>();
    item_desc = new ArrayList<>();
    item_category = new ArrayList<>();
    item_quantity = new ArrayList<>();

    storeDataInArrays();

    ListViewAdapter = new ListViewAdapter(ItemListScreen.this,this, item_id, item_title, item_desc, item_category,
            item_quantity);
    recyclerViewItem.setAdapter(ListViewAdapter);
    recyclerViewItem.setLayoutManager(new LinearLayoutManager(ItemListScreen.this));

Continuation of MainActivity.java

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_item_menu, menu);
    MenuItem item = menu.findItem(R.id.search_items);
    SearchView searchView = (SearchView) item.getActionView();
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            ListViewAdapter.getFilter().filter(query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            ListViewAdapter.getFilter().filter(newText);
            return true;
        }
    });

    return super.onCreateOptionsMenu(menu);
}

And this is my ListViewAdapter (the toLowerCase is not working as intended)

public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.MyItemViewHolder> implements Filterable {

private Context context1;
private Activity activity1;
private ArrayList item_id, item_title,item_desc, item_category, item_quantity, originalList, item_id_org, item_title_org, item_desc_org, item_category_org, item_quantity_org;

ListViewAdapter(Activity activity1, Context context1, ArrayList item_id, ArrayList item_title, ArrayList item_desc, ArrayList item_category,
              ArrayList item_quantity){
    this.activity1 = activity1;
    this.context1 = context1;
    this.item_id_org = item_id;
    this.item_title_org = item_title;
    this.item_desc_org = item_desc;
    this.item_category_org = item_category;
    this.item_quantity_org = item_quantity;
    this.item_id = new ArrayList<>();
    this.item_id.addAll(this.item_id_org);
    this.item_title = new ArrayList<>();
    this.item_title.addAll(this.item_title_org);
    this.item_desc = new ArrayList<>();
    this.item_desc.addAll(this.item_desc_org);
    this.item_category = new ArrayList<>();
    this.item_category.addAll(this.item_category_org);
    this.item_quantity = new ArrayList<>();
    this.item_quantity.addAll(this.item_quantity_org);

}
@NonNull
@Override
public MyItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context1);
    View view = inflater.inflate(R.layout.item_row, parent, false);
    return new MyItemViewHolder(view);
}

@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onBindViewHolder(@NonNull final MyItemViewHolder holder, final int position) {
    holder.item_id_txt.setText(String.valueOf(item_id.get(position)));
    holder.item_title_txt.setText(String.valueOf(item_title.get(position)));
    holder.item_desc_txt.setText(String.valueOf(item_desc.get(position)));
    holder.item_category_txt.setText(String.valueOf(item_category.get(position)));
    holder.item_quantity_txt.setText(String.valueOf(item_quantity.get(position)));
    holder.mainLayout1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(context1, UpdateItemActivity.class);
            intent.putExtra("id", String.valueOf(item_id.get(position)));
            intent.putExtra("title", String.valueOf(item_title.get(position)));
            intent.putExtra("desc", String.valueOf(item_desc.get(position)));
            intent.putExtra("category", String.valueOf(item_category.get(position)));
            intent.putExtra("quantity", String.valueOf(item_quantity.get(position)));
            activity1.startActivityForResult(intent, 1);
        }
    });


}

@Override
public int getItemCount() {
    return item_id.size();
}

class MyItemViewHolder extends RecyclerView.ViewHolder {

    TextView item_id_txt, item_title_txt, item_desc_txt, item_category_txt, item_quantity_txt;
    LinearLayout mainLayout1;

    MyItemViewHolder(@NonNull View itemView) {
        super(itemView);
        item_id_txt = itemView.findViewById(R.id.item_id_txt);
        item_title_txt = itemView.findViewById(R.id.item_title_txt);
        item_desc_txt = itemView.findViewById(R.id.item_desc_txt);
        item_category_txt = itemView.findViewById(R.id.item_category_txt);
        item_quantity_txt = itemView.findViewById(R.id.item_quantity_txt);
        mainLayout1 = itemView.findViewById(R.id.mainLayout1);
        Animation translate_anim = AnimationUtils.loadAnimation(context1, R.anim.translate_anim);
        mainLayout1.setAnimation(translate_anim);
    }

}

    public Filter getFilter() {
    return new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        ArrayList item_id_temp = new TempArrays(),
                item_title_temp = new TempArrays(),
                item_desc_temp = new TempArrays(),
                item_category_temp = new TempArrays(),
                item_quantity_temp = new TempArrays();

        if (constraint.length() == 0) {
            item_id_temp.addAll(item_id_org);
            item_title_temp.addAll(item_title_org);
            item_desc_temp.addAll(item_desc_org);
            item_category_temp.addAll(item_category_org);
            item_quantity_temp.addAll(item_quantity_org);

        } else {
            for(int i=0; i<item_title_org.size(); i++){
                if(item_title_org.get(i).toLowerCase().contains(constraint.toLowerCase())){
                   item_id_temp.add(item_id_org.get(i));
                    item_title_temp.add(item_title_org.get(i));
                    item_desc_temp.add(item_desc_org.get(i));
                    item_category_temp.add(item_category_org.get(i));
                    item_quantity_temp.add(item_quantity_org.get(i));
                }
            }
        }
        FilterResults results = new FilterResults();
        TempArrays ta = new TempArrays();
        ta.item_id = item_id_temp;
        ta.item_title = item_title_temp;
        ta.item_desc = item_desc_temp;
        ta.item_category = item_category_temp;
        ta.item_quantity = item_quantity_temp;
        results.values = ta;
        return results;
    }
    @Override
    public void publishResults(CharSequence constraint, FilterResults results) {
        item_title = (ArrayList<String>) results.values;
        notifyDataSetChanged();
    }
};
    }
ArrayList getFilteredResults(String constraint) {
    ArrayList results = new ArrayList<>();
    for (Object item : originalList) {
        if (item.toString().toLowerCase().contains(constraint)) {
            results.add(item.toString());
        }
    }
    return results;
}


public static class TempArrays extends ArrayList{
    public ArrayList item_id, item_title,item_desc, item_category, item_quantity;

}

}

Solution

  • Try this adapter:

    public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.MyItemViewHolder> implements Filterable {
    
    private Context context1;
    private Activity activity1;
    private ArrayList item_id, item_title,item_desc, item_category, item_quantity;
    //originalList, item_id_org, item_title_org, item_desc_org, item_category_org, item_quantity_org;
    private ArrayList<Integer> index = new ArrayList<>();
    
    ListViewAdapter(Activity activity1, Context context1, ArrayList item_id, ArrayList item_title, ArrayList item_desc, ArrayList item_category,
                    ArrayList item_quantity){
        this.activity1 = activity1;
        this.context1 = context1;
        
        this.item_id = item_id;
        this.item_title = item_title;
        this.item_desc = item_desc;
        this.item_category = item_category;
        this.item_quantity = item_quantity;
        initArrayIndex();
        
    //        this.item_id = new ArrayList<>();
    //        this.item_id.addAll(this.item_id_org);
    //        this.item_title = new ArrayList<>();
    //        this.item_title.addAll(this.item_title_org);
    //        this.item_desc = new ArrayList<>();
    //        this.item_desc.addAll(this.item_desc_org);
    //        this.item_category = new ArrayList<>();
    //        this.item_category.addAll(this.item_category_org);
    //        this.item_quantity = new ArrayList<>();
    //        this.item_quantity.addAll(this.item_quantity_org);
    }
    
    private void initArrayIndex() {
        index.clear();
        for(int i = 0; i < item_title.size(); i++) index.add(i);
    }
    
    @NonNull
    @Override
    public MyItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context1);
        View view = inflater.inflate(R.layout.item_row, parent, false);
        return new MyItemViewHolder(view);
    }
    
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onBindViewHolder(@NonNull final MyItemViewHolder holder, final int position) {
        final int indexedPosition = index.get(position);
        holder.item_id_txt.setText(String.valueOf(item_id.get(indexedPosition)));
        holder.item_title_txt.setText(String.valueOf(item_title.get(indexedPosition)));
        holder.item_desc_txt.setText(String.valueOf(item_desc.get(indexedPosition)));
        holder.item_category_txt.setText(String.valueOf(item_category.get(indexedPosition)));
        holder.item_quantity_txt.setText(String.valueOf(item_quantity.get(indexedPosition)));
        holder.mainLayout1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context1, UpdateItemActivity.class);
                intent.putExtra("id", String.valueOf(item_id.get(indexedPosition)));
                intent.putExtra("title", String.valueOf(item_title.get(indexedPosition)));
                intent.putExtra("desc", String.valueOf(item_desc.get(indexedPosition)));
                intent.putExtra("category", String.valueOf(item_category.get(indexedPosition)));
                intent.putExtra("quantity", String.valueOf(item_quantity.get(indexedPosition)));
                activity1.startActivityForResult(intent, 1);
            }
        });
    }
    
    @Override
    public int getItemCount() {
        return index.size();
        //return item_id.size();
    }
    
    class MyItemViewHolder extends RecyclerView.ViewHolder {
    
        TextView item_id_txt, item_title_txt, item_desc_txt, item_category_txt, item_quantity_txt;
        LinearLayout mainLayout1;
    
        MyItemViewHolder(@NonNull View itemView) {
            super(itemView);
            item_id_txt = itemView.findViewById(R.id.item_id_txt);
            item_title_txt = itemView.findViewById(R.id.item_title_txt);
            item_desc_txt = itemView.findViewById(R.id.item_desc_txt);
            item_category_txt = itemView.findViewById(R.id.item_category_txt);
            item_quantity_txt = itemView.findViewById(R.id.item_quantity_txt);
            mainLayout1 = itemView.findViewById(R.id.mainLayout1);
            Animation translate_anim = AnimationUtils.loadAnimation(context1, R.anim.translate_anim);
            mainLayout1.setAnimation(translate_anim);
        }
    
    }
    
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String searchString = constraint.toString().toLowerCase();
                
                //ArrayList item_id_temp = new TempArrays(),
                //        item_title_temp = new TempArrays(),
                //        item_desc_temp = new TempArrays(),
                //        item_category_temp = new TempArrays(),
                //        item_quantity_temp = new TempArrays();
    
                if (constraint.length() == 0) {
                    //item_id_temp.addAll(item_id_org);
                    //item_title_temp.addAll(item_title_org);
                    //item_desc_temp.addAll(item_desc_org);
                    //item_category_temp.addAll(item_category_org);
                    //item_quantity_temp.addAll(item_quantity_org);
                    
                    initArrayIndex();
                } else {
                    index.clear();
                    for(int i=0; i<item_title.size(); i++){
                        if(item_title.get(i).toString().toLowerCase().contains(searchString)){
                            //item_id_temp.add(item_id.get(i));
                            //item_title_temp.add(item_title.get(i));
                            //item_desc_temp.add(item_desc.get(i));
                            //item_category_temp.add(item_category.get(i));
                            //item_quantity_temp.add(item_quantity.get(i));
                            index.add(i);
                        }
                    }
                }
                FilterResults results = new FilterResults();
                //TempArrays ta = new TempArrays();
                //ta.item_id = item_id_temp;
                //ta.item_title = item_title_temp;
                //ta.item_desc = item_desc_temp;
                //ta.item_category = item_category_temp;
                //ta.item_quantity = item_quantity_temp;
                results.values = index;
                return results;
            }
            @Override
            public void publishResults(CharSequence constraint, FilterResults results) {
                //item_title = (ArrayList<String>) results.values;
                notifyDataSetChanged();
            }
        };
    }
    
    }