I thought they were the same, but they're not. The following code gives an indexOutOfBounds exception when I try to access the "position" index of my dataset, in this case a list of a model I created called Task:
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {
private List<Task> taskList;
private TaskAdapter thisAdapter = this;
// cache of views to reduce number of findViewById calls
public static class TaskViewHolder extends RecyclerView.ViewHolder {
protected TextView taskTV;
protected ImageView closeBtn;
public TaskViewHolder(View v) {
super(v);
taskTV = (TextView)v.findViewById(R.id.taskDesc);
closeBtn = (ImageView)v.findViewById(R.id.xImg);
}
}
public TaskAdapter(List<Task> tasks) {
if(tasks == null)
throw new IllegalArgumentException("tasks cannot be null");
taskList = tasks;
}
// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
final int position = pos;
Task currTask = taskList.get(pos);
taskViewHolder.taskTV.setText(currTask.getDescription());
**taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TRACE", "Closing task at position " + position);
// delete from SQLite DB
Task taskToDel = taskList.get(position);
taskToDel.delete();
// updating UI
taskList.remove(position);
thisAdapter.notifyItemRemoved(position);
}
});**
}
@Override
public int getItemCount() {
//Log.d("TRACE", taskList.size() + " tasks in DB");
return taskList.size();
}
// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item, parent, false);
Task currTask = taskList.get(pos);
//itemView.setBackgroundColor(Color.parseColor(currTask.getColor()));
return new TaskViewHolder(itemView);
}
}
Deleting from my recyclerview gives unexpected results sometimes. Sometimes the element ahead of the one clicked is deleted, other times an indexOutOfBounds exception occurs at "taskList.get(position)".
Reading https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html and https://developer.android.com/training/material/lists-cards.html did not give me any more insight into why this was happening and how to fix it.
It looks like RecyclerView recycles the rows, but I wouldn't expect an indexoutofbounds exception using a smaller subset of numbers to index my list.
ViewHolder is not bound to an item or the given RecyclerView. Adapter is not part of this Adapter (if this Adapter merges other adapters).
RecyclerView has an Adapter with two very important methods that we implement to bind data: RecyclerView. ViewHolder onCreateViewHolder(ViewGroup parent, int viewType);
getItemCount() : RecyclerView calls this method to get the size of the data set.
Like yigit said, RecyclerView works like that:
A B C D
and you add item X via
mItems.add(1, X);
notifyItemInserted(1, 1);
you get
A X B C D
Using holder.getAdapterPosition()
in onClickListener() will give you the right item from dataset to be removed, not the "static" view position. Here's the doc about it onBindViewHolder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With