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);
0 comments:
Post a Comment