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); }
notifyDataSetChanged. Notify any registered observers that the data set has changed. There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred.
RecyclerView has greater support for LayoutManagement including vertical lists, horizontal lists, grids and staggered grids. ListView only supports vertical lists. ListView starts by default with dividers between items and requires customisation to add decorations.
The RecyclerView library provides three layout managers, which handle the most common layout situations: LinearLayoutManager arranges the items in a one-dimensional list.
When used, pass the child Class Object, and in onCreateViewHolder , use Reflection to create the child ViewHolder. When you get an onBindViewHolder, just pass it to the ViewHolder.
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(); }
Tried
public void removeItem(int position) { this.taskLists.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, getItemCount() - position); }
and working like a charm.
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