Wednesday, September 26, 2018

Unable to delete on swipe while searching for an item in SearchView [Inventory App]

Leave a Comment

Actually I'm trying to make an app for inventory.

So after scanning some barcodes I'm adding them to an ArrayList and then in a recyclerView, mine recyclerView has a filter method and a searchView so the user should be able to search throw barcodes and have to be able to delete searched item on swipe.

When I open my recyclerView that is in a dialogAlert and if I delete items all works fine, but when I search for an item and delete it and then I close searchView the item still remain in the recyclerView.

I'll provide here my Adapter code, and the code where I build and delete item in Activity.

Here is code from Activity:

@SuppressLint("SetTextI18n") @TargetApi(Build.VERSION_CODES.KITKAT) public void alertDeleteSingleItem(final int position){     final AlertDialog.Builder mBuilder = new AlertDialog.Builder(InventarioActivity.this);      @SuppressLint("InflateParams") View mView = getLayoutInflater().inflate(R.layout.alert_confirm_delete, null);      final Button yes = mView.findViewById(R.id.btnSI);     final Button no = mView.findViewById(R.id.btnNO);     final TextView text = mView.findViewById(R.id.textView);      text.setText("ELIMINARE " + itemAdapter.getList().get(position).getCodiceArticolo() + " ?");      mBuilder.setView(mView);     final AlertDialog dialog = mBuilder.create();     Objects.requireNonNull(dialog.getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);     dialog.show();       yes.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View view) {             itemAdapter.removeItem(position);             dialog.dismiss();         }     });      no.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View view) {             dialog.dismiss();         }     });  }  public void buildVariableRecycler(View view) {     recyclerView = view.findViewById(R.id.rectclerItems);     recyclerView.setHasFixedSize(true);     RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);     itemAdapter = new ItemAdapter(itemModel);     recyclerView.setLayoutManager(mLayoutManager);     recyclerView.setAdapter(itemAdapter);       new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {         @Override         public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {             return false;         }          @Override         public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {             int position = viewHolder.getAdapterPosition();               if (direction == ItemTouchHelper.RIGHT) {                 alertDeleteSingleItem(position);             }              if (direction == ItemTouchHelper.LEFT) {                 alertDeleteSingleItem(position);             }          }     }).attachToRecyclerView(recyclerView);  } 

While here is my adapter:

    public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ExampleViewHolder>  implements Filterable {       private ArrayList<ItemModel> variantiConstructors;     private List<ItemModel> mFilteredList;       @NonNull     @Override     public ItemAdapter.ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler,parent,false);         RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);         v.setLayoutParams(lp);         return new ItemAdapter.ExampleViewHolder(v);     }      ItemAdapter(ArrayList<ItemModel> exampleList){         variantiConstructors = exampleList;         mFilteredList = variantiConstructors;     }      @Override     public void onBindViewHolder(@NonNull final ItemAdapter.ExampleViewHolder holder, @SuppressLint("RecyclerView") final int position) {         ItemModel item = variantiConstructors.get(position);          holder.desc.setText(item.getCodiceArticolo());         holder.qta.setText(item.getQta());          holder.qta.addTextChangedListener(new TextWatcher() {             @Override             public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {             }              @Override             public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {                 variantiConstructors.get(position).setQta(holder.qta.getText().toString());             }              @Override             public void afterTextChanged(Editable editable) {             }         });           if(position % 2 == 0 ){             holder.itemView.setBackgroundColor(Color.parseColor("#5C5C5C"));          }else if(position % 2 == 1){             holder.itemView.setBackgroundColor(Color.parseColor("#9E9E9E"));         }     }       @Override     public Filter getFilter() {         return new Filter() {             @Override             protected FilterResults performFiltering(CharSequence constraint) {                 final FilterResults oReturn = new FilterResults();                 final ArrayList<ItemModel> results = new ArrayList<>();                 if (mFilteredList == null)                     mFilteredList = new ArrayList<>(variantiConstructors);                 if (constraint != null && constraint.length() > 0) {                     if (mFilteredList != null && mFilteredList.size() > 0) {                         for (final ItemModel cd : mFilteredList) {                             if (cd.getCodiceArticolo().toLowerCase()                                     .contains(constraint.toString().toLowerCase()))                                 results.add(cd);                         }                     }                     oReturn.values = results;                     oReturn.count = results.size(); //newly Aded by ZA                 } else {                     oReturn.values = mFilteredList;                     oReturn.count = mFilteredList.size(); //newly added by ZA                 }                 return oReturn;             }              @SuppressWarnings("unchecked")             @Override             protected void publishResults(final CharSequence constraint,                                           FilterResults results) {                 variantiConstructors = new ArrayList<>((ArrayList<ItemModel>) results.values);                 notifyDataSetChanged();             }         };     }      @Override     public int getItemCount() {         return variantiConstructors.size();     }      public class ExampleViewHolder extends RecyclerView.ViewHolder {          public TextView desc;         public EditText qta;          ExampleViewHolder(View itemView) {             super(itemView);              desc = itemView.findViewById(R.id.Desc);             qta = itemView.findViewById(R.id.Qta);         }     }       public ArrayList<ItemModel> getList(){         return variantiConstructors;     }       public void removeItem(int position){          variantiConstructors.remove(position);         notifyDataSetChanged();     }  } 

After doing some tests I've got that on swipe when I searched for an item it's getting position 0 so that's the problem but how can I get on swipe the right position of the item?

3 Answers

Answers 1

Check the code in the getFilter() method. You can easily make out that this happens because the filter keeps the list of item inside a temp list. And during filtering the main list is switched out.

When you remove an item from your filtered list, you remove from the temp list not from the main list. After knowing this, you may be able to somehow implement the delete via the filtered list as well but I would not be impressed because the getFilter() and SearchView are not meant for this specific case.

And the reason may be that Delete is more of a backend related operation than of the curent UI and above that yours is an inventory app.

So the best you way to implement what you exactly want with more control is not to use getFilter() and SearchView. Just implement your own custom searchview and use the same list for filter and connecting the Delete with your backend. I have done it this way for a similar inventory app and I find it much more convenient.

Answers 2

You are getting deleted result because of it still in temporarily array list which is used for the filter. Update your adapter method,

public void removeItem(int position){          variantiConstructors.remove(position);         mFilteredList.remove(position);         notifyDataSetChanged();     } 

Answers 3

First place these lines where you remove an item :

yourAdapter.remove(yourArrayList.get([INDEX])); yourAdapter.notifyDataSetChanged(); 

then, this line you can call again :

setListAdapter(yourAdapter); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment