EDIT: The real problem was that my LinearLayout
was wrapped in another layout, which caused the incorrect behavior. The accepted answer by Sanvywell has
I'm not sure how these solutions (by @Sanvywell, @HappyKatz and @user2410066) are working for you guys but in my case I needed another check in the onChildDraw
method.
Looks like ItemTouchHelper
keeps ViewHolder
s of removed rows in case they need to be restored. It's also calling onChildDraw
for those VHs in addition to the VH being swiped. Not sure about memory management implications of this behavior but I needed an additional check in the start of onChildDraw
to avoid drawing for "fantom" rows.
if (viewHolder.getAdapterPosition() == -1) {
return;
}
BONUS PART:
I've also wanted to continue drawing as other rows animate to their new positions after a row is swipe deleted, and I couldn't do it within ItemTouchHelper
and onChildDraw
. In the end I had to add another item decorator to do it. It goes along these lines:
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (parent.getItemAnimator().isRunning()) {
// find first child with translationY > 0
// draw from it's top to translationY whatever you want
int top = 0;
int bottom = 0;
int childCount = parent.getLayoutManager().getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getLayoutManager().getChildAt(i);
if (child.getTranslationY() != 0) {
top = child.getTop();
bottom = top + (int) child.getTranslationY();
break;
}
}
// draw whatever you want
super.onDraw(c, parent, state);
}
}
UPDATE: I wrote a blog post on recycler view swipe to delete feature. Someone might find it usefull. No 3rd party lib necessary.
blog post git repo