Reputation: 487
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:
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
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
Reputation: 743
I have a similar problem, I solved it by the following:
// Add 2 method
notifyDataSetChanged()
notifyItemRemoved(position)
Upvotes: 1