A search view is implemented in action bar, the search works fine, but for example, If user search for two characters pa, my list contains 2 data related to the related to pa i.e., pack1,pack2 then data loads in the recycler view. now if user enter another character l, to the previous characters pa, now my search view has pal , but array list doesn't match with the search, the list doesn't contain any item with pal. i.e., now the recycler view is empty. now, if I clear the character l, the list gets reloaded with data pack1, pack2, but result loads 2 times i.e., instead of showing 2 items in recyclerview, it shows 4 items in total. It is duplicating the items, when the search is cleared.
searchview
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_order, menu);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
mOrderAdapter.getFilter().filter(query);
searchView.clearFocus();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if(newText.length()==0){
getData();
searchView.clearFocus();
}
mOrderAdapter.getFilter().filter(newText);
return true ;
}
});
return true;
}
Filter code
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()||charString.length()==0) {
mListFilter = mOrderArrayList;
} else {
List<Order> filteredList = new ArrayList<>();
ArrayList<Order> templist=new ArrayList<Order>();
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
templist.addAll(mListFilter);
}
}
mOrderArrayList.removeAll(templist);
mOrderArrayList.addAll(filteredList);
mListFilter = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mListFilter;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}
Any help is really appreciated.
Adapter code
public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.MyViewHolder> implements Filterable {
private Context mContext;
private List<Order> mListFilter,mOrderArrayList;
private SharedPreferences sharedPreferences;
private Resources r;
public OrderAdapter(Context context, ArrayList<Order> orderList) {
mContext = context;
mListFilter = orderList;
mOrderArrayList = orderList;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
r = context.getResources();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView orderNoView, itemNameView, qtyView, statusView, companyNameView;
private Order currentItem;
MyViewHolder(View view) {
super(view);
orderNoView = view.findViewById(R.id.orderNo);
itemNameView = view.findViewById(R.id.item);
qtyView = view.findViewById(R.id.qty);
statusView = view.findViewById(R.id.status);
companyNameView = view.findViewById(R.id.company);
}
void bind (Order om) { //<--bind method allows the ViewHolder to bind to the data it is displaying
orderNoView.setText(om.getOs_OrderNo());
itemNameView.setText(String.valueOf(om.getItemName()));
qtyView.setText("Qty - " + String.valueOf(om.getOs_Qty()));
statusView.setText(om.getStatusName());
if (sharedPreferences.getString(r.getString(R.string.key_CompanyInUser), "").equals("0")){
companyNameView.setVisibility(View.GONE);
} else {
companyNameView.setText(om.getCustomerName());
}
currentItem = om; //<-- keep a reference to the current item
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.adapter_order, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Order item = mListFilter.get(position);
holder.bind(item);
}
@Override
public int getItemCount() {
return mListFilter.size();
}
@Override
public int getItemViewType(int position){
return position;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
List<Order> filteredList = new ArrayList<>();
if (charString.isEmpty()||charString.length()==0) {
filteredList.addAll(mOrderArrayList);
} else {
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}
}
Clicklistener code
brandView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), brandView,
new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
isRefreshData = true;
startActivity(new Intent(mContext, ViewOrderDetails.class).putExtra("Key-Intent-OrderNo",mOrderArrayList.get(position).getOs_OrderNo()).putExtra("Key-Intent-BrandName",mOrderArrayList.get(position).getos_BrandName()));
}
@Override
public void onLongClick(View view, int position) {
}
}));
Its because you are using addAll
inside a loop in #performFiltering
. Also why you have two local list for filtering? Check the method below it should work . i have removed the extra code and code which is causing the issue .
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
List<Order> filteredList = new ArrayList<>();
if (charString.isEmpty()||charString.length()==0) {
filteredList.addAll(mOrderArrayList);
} else {
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}