I have a RecyclerView , a full View . I need to delete items, with a long press, which is what I'm trying to do.

Here is the adapter (not all, the rest is not needed):

 public class CustomListAdapter_Words extends RecyclerView.Adapter<CustomListAdapter_Words.ViewHolder> { private CreatePage_Fragment mFragment; private ArrayList<ArrayList<String>> mWordsForm_1; public static class ViewHolder extends RecyclerView.ViewHolder { View v; TextView textView_1_form_1; TextView textView_2_form_1; TextView textView_3_form_1; public ViewHolder(View view) { super(view); this.textView_1_form_1 = (TextView) view.findViewById(R.id.text_1); this.textView_2_form_1 = (TextView) view.findViewById(R.id.text_2); this.textView_3_form_1 = (TextView) view.findViewById(R.id.text_3); this.v = view; } } public CustomListAdapter_Words(ArrayList<ArrayList<String>> wordsForm_1, CreatePage_Fragment fragment) { mFragment = fragment; mWordsForm_1 = wordsForm_1; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewHolder myViewHolder; View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_words_form_1, parent, false); myViewHolder = new ViewHolder(view); return myViewHolder; } @Override public void onBindViewHolder(final ViewHolder holder, final int listPosition) { holder.textView_1_form_1.setText(mWordsForm_1.get(listPosition).get(0)); holder.textView_2_form_1.setText(mWordsForm_1.get(listPosition).get(1)); holder.textView_3_form_1.setText(mWordsForm_1.get(listPosition).get(2)); holder.v.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mFragment.onLongClicked(listPosition, 1, mWordsForm_1, listPosition); return true; } }); } } 

When you click the item, the list transfers its position in the list, the List and the position in the ArrayList (let the positions coincide, but do so):

 holder.v.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mFragment.onLongClicked(listPosition, mWordsForm_1, listPosition); return true; } }); 

Here is the method that implements removal:

  public void onLongClicked(int position, ArrayList<ArrayList<String>> list, int positionInList) { listWithRecord.remove(position); ((CustomListAdapter_Words) adapter).notifyItemRemoved(position); } 

The problem is that the first removal is successful. Everything is deleted correctly, but then RecyclerView changes the position numbers in the list for all View . View that does not reboot on the screen and, if you delete one View , another is deleted (more than as many as I deleted). To make it clearer:

I have three elements (the first column is the position in the list):

 1 - персик (говорит, что первый в списке) 2 - абрикос (говорит, что второй в списке) 3 - слива (говорит, что третья в списке) 

If you delete the first element, it turns out like this:

 1 - абрикос (говорит, что второй в списке) 2 - слива (говорит, что третья в списке) 

As a result of the removal of the first element, the second element is deleted, and, as a result, the removal of the second - writes that I am referring to a nonexistent list index.

Question: how to fix this error? How can I return a valid position in the list through a click listener?

  • Do you have ochepyatka or are you using some external variable? positionInRecycler & positionInList - JuriySPb
  • And listWithRecord & list in the same place. - Yuriy SPb
  • And what if you do it right from the adapter? - Yuriy SPb
  • @Yuriy SPb, not a typo, just used public variables. Long to explain, but I corrected :). Delete from the fragment, and transfer the position to the fragment. - user189127
  • @Yuriy SPb, but if you need through an adapter - I will do it through an adapter! I need all the solutions to this problem ... - user189127

1 answer 1

ViewHolder has a method getAdapterPosition ()

 holder.v.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mFragment.onLongClicked(getAdapterPosition(), mWordsForm_1); return true; } }); 

A long click put like this:

  public class ViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener { View v; TextView textView_1_form_1; TextView textView_2_form_1; TextView textView_3_form_1; public ViewHolder(View view) { super(view); view.setOnLongClickListener(this); this.textView_1_form_1 = (TextView) view.findViewById(R.id.text_1); this.textView_2_form_1 = (TextView) view.findViewById(R.id.text_2); this.textView_3_form_1 = (TextView) view.findViewById(R.id.text_3); this.v = view; @Override public boolean onLongClick(View v) { mFragment.onLongClicked(getAdapterPosition(), mWordsForm_1); return true; } } } 
  • The getAdapterPosition() method helped! Let the listener announce in the holder did not work (it is static, but the fragment is not), but I replaced listPosition with getAdapterPosition and everything worked perfectly! - user189127