I have a dialog in the application that displays a list of files attached to the letter. The list is filled with data from the array in which there are elements in json format. Next, I try to delete it by swipe. If I understand correctly, it will remove not only the element from the array but also the element from the list. Everything seems fine, but there are a few problems. When I delete an item, I’m left an empty space in the list and the list is not updated. And after re-calling the dialog with the list, I don’t fill the list at all, although the logs show that the array is not empty. Here is how I invoke a dialog with a list of attachments:

attachment.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { if (array.size() > 0) { if (movieList.size() > 0) { movieList.clear(); showDialog(SHOW_ATTACHED_FILES); prepareList(); } else { showDialog(SHOW_ATTACHED_FILES); prepareList(); } } else { Toast.makeText(WriteResponseMess.this, "NO attached files", Toast.LENGTH_SHORT).show(); } return true; } }); 

and here is the construction of a dialogue:

 dialog = new Dialog(WriteResponseMess.this); dialog.setContentView(R.layout.show_attachment); dialog.setCanceledOnTouchOutside(true); final RecyclerView recyclerView = dialog.findViewById(R.id.lv); final AttachmentAdapter mAdapter = new AttachmentAdapter(movieList); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getBaseContext()); recyclerView.setLayoutManager(mLayoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { @Override public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) { return false; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int position) { for (int i = 0; i < array.size(); i++) { array.remove(i); } } }; new ItemTouchHelper(simpleCallback).attachToRecyclerView(recyclerView); 

Here is the function that fills the list:

 public void prepareList() { for (int i = 0; i < array.size(); i++) { JsonObject object = array.get(i).getAsJsonObject(); Log.w("MY_TAG", String.valueOf(object.get("filename"))); Log.w("MY_TAG", String.valueOf(object.get("data"))); Integer data = object.get("data").toString().getBytes().length; movieList.add(new FileList(String.valueOf(object.get("filename")), String.valueOf(data))); } } 

Here, for example, I found such a solution, but after its introduction into the svayp listener, my application starts crashing for various reasons. I can not understand where and what I am doing wrong. I hope for your help and useful tips.

update

  @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int position) { for (int i = 0; i < array.size(); i++) { array.remove(i); // удаляСм запись ΠΈΠ· источника (ΠΊΠ°ΠΊ я понял) mAdapter.notifyItemRemoved(position); // увСдомляСм Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ ΠΎΠ± ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ movieList.remove(position); // удаляСм запись ΠΈΠ· ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° ---- здСсь ошибка } } 

error code:

 java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 
  • The cycle, then why? You want to delete one element and not all at once. - woesss 1:58
  • yes, but I understand that the indices in the list do not correspond to the indices of the array, or is it not? just if the cycle does not insert another error - Andrew Goroshko
  • You copy my code. You have one position in the cycle ( position ) and when there are fewer elements in the list than position and an error is fired. - woesss
  • @woesss, I copied, removed the cycle, did everything as you have, but still throws a mistake - java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 although everything is yours - Andrew Goroshko
  • one
    You misled me with the name of the parameter - this is not the position but the direction of the svayp. Updated code. - woesss

1 answer 1

After removing an item, you probably need to notify the adapter so that it is redrawn: mAdapter.notifyItemRemoved(position) . Only it is not clear what you are doing in onSwiped ...
Maybe it meant:

 @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); array.remove(position); // удаляСм запись ΠΈΠ· источника (ΠΊΠ°ΠΊ я понял) movieList.remove(position); // удаляСм запись ΠΈΠ· ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° mAdapter.notifyItemRemoved(position); // увСдомляСм Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ ΠΎΠ± ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ } 

Update: If I understand the meaning of your code correctly, then it should work like this:

 attachment.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { if (array.size() > 0) { showDialog(SHOW_ATTACHED_FILES); } else { Toast.makeText(WriteResponseMess.this, "NO attached files", Toast.LENGTH_SHORT).show(); } return true; } }); 

 final RecyclerView recyclerView = dialog.findViewById(R.id.lv); prepareList(); final AttachmentAdapter mAdapter = new AttachmentAdapter(movieList); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getBaseContext()); recyclerView.setLayoutManager(mLayoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(mAdapter); 

 public void prepareList() { movieList.clear(); for (int i = 0; i < array.size(); i++) { JsonObject object = array.get(i).getAsJsonObject(); Log.w("MY_TAG", String.valueOf(object.get("filename"))); Log.w("MY_TAG", String.valueOf(object.get("data"))); Integer data = object.get("data").toString().getBytes().length; movieList.add(new FileList(String.valueOf(object.get("filename")), String.valueOf(data))); } } 
  • your method does not work, throws fatal_exception - java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 per line array.remove(position) - Andrew Goroshko
  • And what is the condition in attachment.setOnLongClickListener ? Because of it, the adapter can display not only what is in the array - hence the output beyond the array. - woesss
  • if this condition is not written, then with each long press I add all the elements to the list in a new way, as a result of each element there may be a few pieces there - Andrew Goroshko
  • If you need to show only the contents of the array - remove the condition if (movieList.size() > 0) and clean movieList.clear() unconditionally. Although it seems that the sequence of actions is violated and the dialogue shows not relevant content. - woesss
  • Yes, it solved some of the problems, but the application crashes anyway, threw the removal of an element into a cycle, but now the adapter update throws me out - Andrew Goroshko