Switching ListView to RecyclerView will simplify the job.
You can find the whole article on Styling Android and all the code here.
This code uses OnItemTouchListener to determine when an item needs to be dragged. There is an ImageView above the RecyclerView with an image of an object being moved to bring it to life cheaply.
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 a drag and drop ( 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); }
Code written by Mark Allison on StylingAndroid.
Edit:
But I do not know how to get the position of an element when dragging end
The answer is in part 7 on Android styling.
View view = recyclerView.findChildViewUnder(0, y);
And how can I turn off the drag and drop of the Folder and Title elements? Just allow drag and drop file?
You can do this using multiple ViewTypes (file, folder and title). Then you can use getItemViewType in the DragController to start the file-only move.