@Override public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final int x = (int) ev.getX(); final int y = (int) ev.getY(); if (action == MotionEvent.ACTION_DOWN && x > (this.getWidth() - 60)) mDragMode = true; if (!mDragMode) return super.onTouchEvent(ev); switch (action) { case MotionEvent.ACTION_DOWN: mStartPosition = pointToPosition(x, y); if (mStartPosition != INVALID_POSITION) { mItemPosition = mStartPosition - getFirstVisiblePosition(); mDragPointOffset = y - getChildAt(mItemPosition).getTop(); mDragPointOffset -= ((int) ev.getRawY()) - y; startDrag(mItemPosition, y); drag(50, y); } else mDragMode = false; break; case MotionEvent.ACTION_MOVE: drag(50, y); final int mCurrentPosition = pointToPosition(x, y); if ((y < 100) && (mCurrentPosition >= 0)) { this.smoothScrollToPosition(mCurrentPosition - 1); mDragListener.onStopDrag(getChildAt(mItemPosition)); } else if (((y - getHeight()) < 100) && ((mCurrentPosition > 0) && (mCurrentPosition < this.getCount()))) { this.smoothScrollToPosition(mCurrentPosition + 1); mDragListener.onStopDrag(getChildAt(mItemPosition)); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: default: mDragMode = false; mEndPosition = pointToPosition(x, y); stopDrag(mStartPosition - getFirstVisiblePosition()); if (mDropListener != null && mStartPosition != INVALID_POSITION && mEndPosition != INVALID_POSITION) mDropListener.onDrop(mStartPosition, mEndPosition); break; } return true; }