bauerca / drag-sort-listview

Android ListView with drag and drop reordering.
3.2k stars 1.44k forks source link

NPE when removing last item from adapter #80

Open oginorasta opened 11 years ago

oginorasta commented 11 years ago

When removing last item from adapter programmatically and call notifyDataSetChanged, there is somehow a call to onTouchEvent still in the pipeline with mDragState=DRAGGING casing continueDrag() to get called and finally updateFloatView() where finally getCount() - numFooters - 1 - firstPos returns -1 and getChildAt(-1) returns null.

I fixed this with the following code snippet: int index = getCount() - numFooters - 1 - firstPos; if (lastPos >= getCount() - numFooters - 1 && index >= 0) { bottomLimit = getChildAt(index).getBottom(); }

bauerca commented 11 years ago

Hm. So you must be dragging while your app removes the last item or else onTouchEvent wouldn't get called. When you call notifyDataSetChanged(), it should trigger dslv to abort the drag.

I'd like to know more about how you remove the last item and call notifyDataSetChanged(). Code is best ;)

Your fix is good, but I worry that this may be a more subtle problem. Thanks for the additional info.

oginorasta commented 11 years ago

To start from the beginning, I was trying to build a drag and drop between dlsv's in a viewpager. For this I had to overwrite dlsv to expose a draggedOnEdgeListener. When this is fired the fragment (listener) should remove the current item from dlsv_1's adapter add it to dlsv_2's adapter call notifyDataSetChanged() on both and start a drag on the second dlsv with all the necessary arguments. Well what I investigated was, that when dlsv_1 only has 1 item which was going to get removed cancelDrag() was called from the dataSetObserver but the above scenario happened, from the logs I can tell that the onTouchEvent was definitely called after cancelDrag(). Btw. I also failed to relaunch the drag process while on dlsv_2 while a finger was still on the phone that's why I leave it by that. Sry that I haven't any code snippet but the only think I could paste would be the trivial adapter logic.