Wenn Sie Ihre ListView
auf RecyclerView
umschalten, wird die Arbeit viel einfacher.
Sie können den ganzen Artikel auf Styling Android und den gesamten Code finden sollte here.
Dieser Code verwendet OnItemTouchListener
zu erkennen, wenn ein Element gezogen werden. Es gibt eine ImageView
über der RecyclerView
mit einem Bild des Elements bewegt werden, um es billig zu animieren.
Die 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);
}
}
Starten und Beenden des 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);
}
Der Code wird geschrieben von Mark Allison on StylingAndroid.
Edit:
Aber ich weiß nicht, wie die Position des Elements zu erhalten, wenn schleppt Ende
Die Antwort in part 7 auf Styling Android befindet.
View view = recyclerView.findChildViewUnder(0, y);
Und wie kann ich ziehen auf Ordner und Kopfelement zu deaktivieren? Einfach das Ziehen von Dateielement zulassen?
Sie können dies tun, indem Sie mehrere ViewTypes (Datei, Ordner & Header) verwenden. Dann können Sie getItemViewType in DragController
verwenden, um die Bewegung nur für Dateien zu starten.
Sie könnten 'RecyclerView' mit' ItemTouchHelper' aus der Support-Bibliothek verwenden? –
Wenn ich zu 'RecyclerView' wechsel, ist es einfacher, das zu tun? – R4j
Es sollte sein. Ich habe es nicht benutzt, aber 'ItemTouchHelper' ist zum Hinzufügen von Drag & Drop und Swipe, um die Unterstützung von' RecyclerView' zu verwerfen. Sehen Sie sich die 'ItemTouchHelper'-Dokumente an, um zu sehen, ob Sie ein Beispiel online finden können. Ich kann nicht verstehen, warum deine Frage nicht mehr Aufmerksamkeit bekommt, es gibt viele Bibliotheken, die da draußen sind, um so etwas zu tun. –