2015-12-20 4 views
5

ich eine Listenansicht mit verschiedenen Elementtypen haben: Header, Ordner und die Datei wie folgt aus:Drag Drop Listview-Element in ein anderes Element

enter image description here

Nun würde Ich mag Drag-Datei Artikel implementieren und es fallen in Ordner-Element und erhalten Sie die Quell- und Zielposition.Ich möchte nicht die Zielposition ändern (neu anordnen) beim Ziehen wie einige Drag-Sortierung Listenansicht Bibliotheken.

Gibt es einen Vorschlag, mit zu beginnen?

+0

Sie könnten 'RecyclerView' mit' ItemTouchHelper' aus der Support-Bibliothek verwenden? –

+0

Wenn ich zu 'RecyclerView' wechsel, ist es einfacher, das zu tun? – R4j

+0

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. –

Antwort

1

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.

+0

Danke. Ich versuchte es. Aber ich weiß nicht, wie man die Position eines Gegenstandes bekommt, wenn man am Ende zieht. Und wie kann ich das Ziehen von 'Folder' und' Header' deaktivieren? Einfach erlauben, 'File' zu ​​ziehen? – R4j

+0

@ R4j bearbeitet meine Antwort – LordRaydenMK

+0

Es funktioniert. Du bist mein Held, Mann. Ich danke dir sehr! – R4j