Android List View Drag and Drop Sort

Android List View with BaseAdapter Drag and Drop sort

Use arraylist of your Model.

private ArrayList<YourModel> albumList = new ArrayList<YourModel>();
//add item in your list.

DragSortListView listView = (DragSortListView) findViewById(R.id.lv_test);

ReorderAlbumAdapter adapter = new ReorderAlbumAdapter(this, albumList);

listView.setAdapter(adapter);
listView.setDropListener(onDrop);
listView.setRemoveListener(onRemove);

private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
@Override
public void drop(int from, int to) {
if (from != to) {
AlbumModel item = adapter.getItem(from);
adapter.remove(item);
adapter.insert(item, to);
}
}
};



private DragSortListView.RemoveListener onRemove = new DragSortListView.RemoveListener() {
@Override
public void remove(int which) {
adapter.remove(adapter.getItem(which));
}
};

XML for listview is:

<com.mobeta.android.dslv.DragSortListView
android:id="@+id/lv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
dslv:collapsed_height="2dp"
dslv:drag_enabled="true"
dslv:drag_handle_id="@drawable/ic_launcher"
dslv:drag_scroll_start="0.33"
dslv:drag_start_mode="onMove"
dslv:float_alpha="0.6"
dslv:max_drag_scroll_speed="0.5"
dslv:remove_enabled="true"
dslv:remove_mode="flingRemove"
dslv:slide_shuffle_speed="0.3"
dslv:sort_enabled="true"
dslv:track_drag_sort="false"
dslv:use_default_controller="true" />

You should use arrayadapter for your model. Hope it will help you.

Drag drop Listview item into another item

Switching your ListView to RecyclerView will make things a lot easier.

You can find the whole article on Styling Android and the whole code here.

This code uses OnItemTouchListener to detect when an item should be dragged. There is an ImageView above the RecyclerView with an image of the item being moved to cheaply animate it.

The OnItemTouckListener (DragController.java):

public class DragController implements RecyclerView.OnItemTouchListener {
private RecyclerView recyclerView;
private ImageView overlay;
private final GestureDetectorCompat gestureDetector;

private boolean isDragging = false;

public DragController(RecyclerView recyclerView, ImageView overlay) {
this.recyclerView = recyclerView;
this.overlay = overlay;
GestureDetector.SimpleOnGestureListener longClickGestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
isDragging = true;
dragStart(e.getX(), e.getY());
}
};
this.gestureDetector = new GestureDetectorCompat(recyclerView.getContext(), longClickGestureListener);
}

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if (isDragging) {
return true;
}
gestureDetector.onTouchEvent(e);
return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
View view = recyclerView.findChildViewUnder(x, y);
if (e.getAction() == MotionEvent.ACTION_UP) {
dragEnd(view);
isDragging = false;
} else {
drag(y, view);
}
}

Starting and ending the drag (DragController.java):

private boolean isFirst = true;
private static final int ANIMATION_DURATION = 100;
private int draggingItem = -1;
private float startY = 0f;
private Rect startBounds = null;

private void dragStart(float x, float y) {
View draggingView = recyclerView.findChildViewUnder(x, y);
View first = recyclerView.getChildAt(0);
isFirst = draggingView == first;
startY = (y - draggingView.getTop());
paintViewToOverlay(draggingView);
overlay.setTranslationY(y - startY);
draggingView.setVisibility(View.INVISIBLE);
draggingItem = recyclerView.indexOfChild(draggingView);
startBounds = new Rect(draggingView.getLeft(), draggingView.getTop(), draggingView.getRight(), draggingView.getBottom());
}

private void drag(int y, View view) {
overlay.setTranslationY(y - startY);
}

private void dragEnd(View view) {
overlay.setImageBitmap(null);
view.setVisibility(View.VISIBLE);
view.setTranslationY(overlay.getTranslationY() - view.getTop());
view.animate().translationY(0f).setDuration(ANIMATION_DURATION).start();
}

private void paintViewToOverlay(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
overlay.setImageBitmap(bitmap);
overlay.setTop(0);
}

The code is written by Mark Allison on StylingAndroid.

Edit:

But I don't know how to get the position of item when dragging is end

The answer is located in part 7 on Styling Android.

View view = recyclerView.findChildViewUnder(0, y);

And how can I disable drag on Folder and Header item? Just allow dragging File item?

You can do this by using multiple ViewTypes (file, folder & header). Then you can use getItemViewType in DragController to start the movement only for files.

Drag Drop and Reorder elements in ListView

I think your code keeps adding the first item to the second position, but the second item gets removed. This happens internally in the ArrayList, not in the GUI.

I suggest a technique that just swaps the two items, basic swapping using a temporary object. This time the temp is obj1.
Sample code using your style:

public void swapItems(int i, int i2) {
NavigationDrawerFragment.ListItem obj1 = myItems.get(i);
myItems.set(i, myItems.get(i2);
myItems.set(i2, obj1);
}

Note: I am using the ArrayList set method instead of add().



Related Topics



Leave a reply



Submit