using notifyItemRemoved or notifyDataSetChanged with RecyclerView in Android
Solution 1
As @pskink suggested it was supposed to be (index+1) in my case with notifyItemRemoved(index+1)
, probably because i am reserving the top index i.e. position=0
for a header.
Solution 2
Use notifyItemRangeChanged(position, getItemCount()); after notifyItemRemoved(position);
You don't need to use index, just use position. See code below.
private List<DetectedIssue> issues = new ArrayList<DetectedIssue>();
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
if(position >0){
RiskViewHolder riskHolder = (RiskViewHolder)holder;
riskHolder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
issues.remove(position);
notifyItemRemoved(position);
//this line below gives you the animation and also updates the
//list items after the deleted item
notifyItemRangeChanged(position, getItemCount());
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public int getItemCount() {
return issues.size();
}
Solution 3
Tried
public void removeItem(int position) {
this.taskLists.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount() - position);
}
and working like a charm.
Solution 4
my mistake , notifyItemChanged(position) is helpless,the item of position can be removed ,and the item of position+1 is fine,but the items start from position+2,you will get an Exception, please use notifyItemRangeChanged(position,getItemCount()); after notifyItemRemoved(position);
like this:
public void removeData(int position) {
yourdatalist.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,getItemCount());
}
Solution 5
Use this it is working perfectly.
issues.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, issues.size());
revolutionary
Updated on September 27, 2021Comments
-
revolutionary over 2 years
I am creating a list of cards to display using the RecyclerView, where each card has a button to remove that card from the list.
When i use notifyItemRemoved() to remove the card in the RecyclerView, it removes the item and animates fine but the data in the list is not updated correctly.
If instead of that, i switch to the notifyDataSetChanged() then the items in list are removed and updated correctly, but then the cards dont animate.
Does someone has any experience in using the notifyItemRemoved() and know why it behaves differently than notifyDataSetChanged?
Here is some peiece of code that i am using:
private List<DetectedIssue> issues = new ArrayList<DetectedIssue>(); @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element if(position >0){ RiskViewHolder riskHolder = (RiskViewHolder)holder; final int index = position - 1; final DetectedIssue anIssue = issues.get(index); riskHolder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { int index = issues.indexOf(anIssue); issues.remove(anIssue); notifyItemRemoved(index); //notifyDataSetChanged(); } catch (SQLException e) { e.printStackTrace(); } } }); } } @Override public int getItemCount() { return (issues.size()+1); }
-
Viral Patel over 8 yearsplease provide details on what will change by doing this and how it will help resolve the issue.
-
Juan Cruz Soler over 7 yearsFrom documentation: "You should only use the position parameter while acquiring the related data item inside this method and should not keep a copy of it. If you need the position of an item later on (e.g. in a click listener), use RecyclerView.ViewHolder.getAdapterPosition() which will have the updated adapter position."
-
marcos E. about 7 yearsYou should use getAdapterPosition as the documentation states, you´re on risk of creating inconsistencies.
-
Yohan Dahmani almost 7 years@Akshay Mahajan Old thread sorry, but
notifyItemRemoved(position);
works just fine alone (with animation). WhatnotifyItemRangeChanged(position, getItemCount());
is doing ? I can't see the difference. Thank you -
Michał Ziobro over 6 yearsShouldn't be getItemCount() - position, as itemCount means the count of items after removed item?
-
Travis Castillo over 6 yearsyes, the second parameter is range of changed items. using item count means that every item after the position is changing.
-
hamena314 about 6 yearsCould you explain why you use
getItemCount() - position
instead of justgetItemCount()
? -
Bajrang Hudda over 5 years@YohanDahmani, notifyItemRemoved(position); won't work if you are trying on last item..IndexOutOfBoundException you gonna get.
-
Jay over 5 years@hamena314 actually notifyItemRangeChanged(int position, int itemCount) ment tha at "position" items have changed and from "position" , " itemCount" items have changed so it is wise that to pass only items after "positon" instead passing list of all the items. Or instead passing "getItemCount() - position" we can pass getItemCount().
-
Manuel almost 5 yearsThis answer is nonsensical. Both
notifyItemRemoved
andnotifyItemRangeChanged
are doing the same thing. Why this answer has so many upvotes is a mystery. -
ralphgabb over 3 yearsthis worked. the position of the row object will also be updated.
-
Arbaz.in about 3 yearsgetting error while removing last element of array list using this notifyItemRemoved(last pos) any solution for same?
-
sree_sg about 3 yearscan you check this? if(numbers.isEmpty()) notifyDataSetChanged () else notifyItemRemoved(modPosition);