android drag and drop listview,listview - Android List View Drag and Drop sort - Stack Overflow

雍焱
2023-12-01

I recently stumbled upon this great Gist that gives a working implementation of a drag sort ListView, with no external dependencies needed.

Basically it consists on creating your custom Adapter extending ArrayAdapter as an inner class to the activity containing your ListView. On this adapter one then sets an onTouchListener to your List Items that will signal the start of the drag.

In that Gist they set the listener to a specific part of the layout of the List Item (the "handle" of the item), so one does not accidentally move it by pressing any part of it. Personally, I preferred to go with an onLongClickListener instead, but that is up to you to decide. Here an excerpt of that part:

public class MyArrayAdapter extends ArrayAdapter {

private ArrayList mStrings = new ArrayList();

private LayoutInflater mInflater;

private int mLayout;

//constructor, clear, remove, add, insert...

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

ViewHolder holder;

View view = convertView;

//inflate, etc...

final String string = mStrings.get(position);

holder.title.setText(string);

// Here the listener is set specifically to the handle of the layout

holder.handle.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View view, MotionEvent motionEvent) {

if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

startDrag(string);

return true;

}

return false;

}

});

// change color on dragging item and other things...

return view;

}

}

This also involves adding an onTouchListener to the ListView, which checks if an item is being dragged, handles the swapping and invalidation, and stops the drag state. An excerpt of that part:

mListView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View view, MotionEvent event) {

if (!mSortable) { return false; }

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN: {

break;

}

case MotionEvent.ACTION_MOVE: {

// get positions

int position = mListView.pointToPosition((int) event.getX(),

(int) event.getY());

if (position < 0) {

break;

}

// check if it's time to swap

if (position != mPosition) {

mPosition = position;

mAdapter.remove(mDragString);

mAdapter.insert(mDragString, mPosition);

}

return true;

}

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_OUTSIDE: {

//stop drag state

stopDrag();

return true;

}

}

return false;

}

});

Finally, here is how the stopDrag and startDrag methods look like, which handle the enabling and disabling of the drag process:

public void startDrag(String string) {

mPosition = -1;

mSortable = true;

mDragString = string;

mAdapter.notifyDataSetChanged();

}

public void stopDrag() {

mPosition = -1;

mSortable = false;

mDragString = null;

mAdapter.notifyDataSetChanged();

}

 类似资料: