Harry Adams
Harry Adams

Reputation: 487

OnClick to Remove Items From RecyclerView?

I have a RecyclerView item XML which has two TextViews to be filled in when each item is created. These are then displayed in a vertical RecyclerView. My intent is to add an OnLongClick action to display a dialogue box to confirm whether the user would like to remove this item. If confirmed, I'd like to immediately remove this item from the display and the data stored in the adapter.

Code:

package uk.ac.aber.dcs.haa14.assignment.classes;

public class DictionaryRecyclerViewAdapter extends RecyclerView.Adapter<DictionaryRecyclerViewAdapter.DictionaryViewHolder> {

public List<String> primaryWords;
public List<String> secondaryWords;
Context context;
int size;

public DictionaryRecyclerViewAdapter(LinkedHashMap<String,String> wordPairs, Context inContext){
    primaryWords = new ArrayList<>(wordPairs.keySet());
    secondaryWords = new ArrayList<>(wordPairs.values());
    this.size = wordPairs.size();
    this.context = inContext;
}

@NonNull
@Override
public DictionaryViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.dictionary_words_recycler_item,viewGroup,false);
    return new DictionaryViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull DictionaryViewHolder dictionaryViewHolder, int i) {
    dictionaryViewHolder.bind(primaryWords.get(i), secondaryWords.get(i));
}

@Override
public int getItemCount() {
    return size;
}

class DictionaryViewHolder extends RecyclerView.ViewHolder {

    TextView leftWord;
    TextView rightWord;

    public DictionaryViewHolder(View itemView) {
        super(itemView);
        final View tempView = itemView;
        leftWord = itemView.findViewById(R.id.dictRecyclerViewLeftWord);
        rightWord = itemView.findViewById(R.id.dictRecyclerViewRightWord);
    }

    public void bind(String primWord, String secWord){
        leftWord.setText(primWord);
        rightWord.setText(secWord);

        itemView.setOnLongClickListener(new View.OnLongClickListener(){
            @Override
            public boolean onLongClick(View view) {
                DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch(which){
                            case DialogInterface.BUTTON_POSITIVE:
                                int position = getAdapterPosition();
                                primaryWords.remove(position);
                                secondaryWords.remove(position);
                                notifyItemRangeChanged(position, primaryWords.size());
                                //TODO - Call Globals for remove word from lists
                                break;
                            case DialogInterface.BUTTON_NEGATIVE:
                                break;

                        }
                    }
                };
                AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
                builder.setMessage("Would you like to delete this word pair?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
                return true;
            }
        });
    }
}
}

Eventually I'd like to have the user add new pairs via a Floating Action Button, but one thing at a time. For the time being, five items are created for the RecyclerView:

Android Screenshot

Where each row/pair is an individual item in the RecyclerView

The error:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.ac.aber.dcs.haa14.assignment, PID: 26412
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
    at java.util.ArrayList.get(ArrayList.java:437)
    at uk.ac.aber.dcs.haa14.assignment.classes.DictionaryRecyclerViewAdapter.onBindViewHolder(DictionaryRecyclerViewAdapter.java:44)
    at uk.ac.aber.dcs.haa14.assignment.classes.DictionaryRecyclerViewAdapter.onBindViewHolder(DictionaryRecyclerViewAdapter.java:21)
    at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
    at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
...

Upvotes: 0

Views: 392

Answers (2)

lionscribe
lionscribe

Reputation: 3513

Your mistake is that getItemCount() is always returning size, whose value does not change. Just change it to return primaryWords.size(), (and get rid of the size field), and you will be fine.

Upvotes: 1

mducc
mducc

Reputation: 743

I have a similar problem, I solved it by the following:

// Add 2 method 
notifyDataSetChanged()
notifyItemRemoved(position)

Upvotes: 1

Related Questions