Reputation: 4079
I'm seeing odd behavior in a RecyclerView
using a GridLayoutManager
with 2 spans.
I'm trying to get two columns of items:
0 1
2 3
4 5
6 7
... and so on
To achieve this, I'm creating a GridLayoutManager
like so:
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
gridLayoutManager.setOrientation(GridLayoutManager.VERTICAL);
Initially this behaves perfectly. My items appear in the order I want them to.
However, I also need to be able to remove items from the list, and then undo the removal if the user acts quickly enough.
To remove items and then allow undo/insertion of the item back in, I have the following logic executed when a user hits a "remove" button in the RecyclerView
items.
final Item = mItems.getItem(position);
mItems.remove(position);
notifyItemRemoved(position);
// Give the user a chance to undo the removal
Snackbar.make(getView(),
"Item Removed", Snackbar.LENGTH_LONG)
.setAction(R.string.item_removed_snackbar_undo, new View.OnClickListener()
{
@Override
public void onClick(View view)
{
mItems.add(position, item);
notifyItemInserted(position);
}
}).show();
mItems
represents the list of items in my adapter. position
represents the adapter position of the item that had the remove button clicked.
Removing items behaves perfectly. I am able to remove items, and items animate to fill in the empty spaces. However, when I try to undo the deletion and add the item back, the recycler view gets messed and empty spaces are inserted. For example, if I had the following items, and I removed item 2, then undid the removal this is what would happen:
0 1
2 3
remove 2
0 1
3
add 2 back
0 1
2
3
At this point, an "empty" view exists where 3 should be placed (second row, second column). If I query the size of the adapter I still get 4 items, but somehow the items are spread out to take 5 positions total. Touching the empty space does nothing, but if I reorient/config change the layout goes back to
0 1
2 3
as expected.
Am I doing something wrong?
Thanks, Zach
Upvotes: 2
Views: 1726
Reputation: 4079
I found out the problem!
I am calling mRecyclerView.scrollToPosition(position)
after my logic to re-insert the item. I mistakenly took this piece out of my code above as I thought it was unrelated (I will be much more careful in the future).
Anyways, it seems that having this call in results in the funky behavior. If I removed that call everything works as expected. I suspect it was canceling the animation or causing something else to not work properly.
Now I would still like to have my item visible (in case the user removed it, scroll such that it would be offscreen, and then hits undo), but I will figure that out later - this is good enough for now.
Upvotes: 3