Zach
Zach

Reputation: 4079

RecyclerView with GridLayoutManager insert item wrong position

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

Answers (1)

Zach
Zach

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

Related Questions