So erstellen Sie Listenelemente, die DragEvents nach dem Bildlauf erhalten

9

Kurzversion:

  • Gibt es eine Möglichkeit, dass eine neu erstellte Ansicht DragEvent s einer bereits laufenden Drag-and-Drop-Operation erhält?

Es gibt Wie registriere ich ein DragEvent, während es bereits in einem ist, und habe es im aktuellen DragEvent zu hören? , aber ich hätte gerne eine sauberere Lösung.

Die vorgeschlagene GONE- & gt; VISIBLE-Problemumgehung ist recht komplex, um "richtig" zu sein, weil Sie sicherstellen müssen, dass sie nur verwendet wird, wenn ein Listenelement in allen aktuellen Listenansichtselementen nicht bedingungslos sichtbar wird. In diesem ist der Hack etwas undicht ohne noch mehr Workaround-Code, um es richtig zu machen.

Lange Version:

Ich habe ein ListView . Die Elemente von ListView sind benutzerdefinierte Ansichten, die verschiebbare Symbole (kleine Kästchen) enthalten, z. ähnlich wie:

Es ist möglich, die kleinen Kästchen zwischen die Elemente von ListView zu ziehen, wie das Sortieren von Elementen in Boxen. Der Drag-Handler für die Listenelemente ist mehr oder weniger trivial:

%Vor%

Das Ziehen beginnt, wenn Sie den Mauszeiger über ein Symbol halten und anfangen zu ziehen (d. h. es über einen kleinen Schwellenwert hinaus bewegen).

Nun ist die Bildschirmgröße jedoch möglicherweise nicht ausreichend, um alle Felder zu enthalten und somit muss ListView durchlaufen werden. Ich habe auf die harte Art herausgefunden, dass ich das Scrollen selbst durchführen muss, da ListView beim Ziehen nicht automatisch scrollt.

In kommt ListViewScrollingDragListener :

%Vor%

Dies scrollt im Grunde die ListView , wenn Sie in der Nähe der oberen oder unteren Grenzen des sichtbaren Bereichs ziehen. Es ist nicht perfekt, aber es ist gut genug.

Allerdings gibt es einen Haken:

Wenn die Liste zu einem zuvor unsichtbaren Element scrollt, erhält dieses Element DragEvent s nicht. Es wird nicht ausgewählt (hervorgehoben), wenn ein Symbol darüber gezogen wird oder Tropfen akzeptiert werden.

Irgendwelche Ideen, wie man die "gescrollten" Ansichten macht, erhalten DragEvent s von der bereits aktiven Drag-and-Drop-Operation?

    
dhke 23.04.2015, 13:56
quelle

1 Antwort

3

Das grundlegende Problem besteht also darin, dass ViewGroup (das heißt ListView extends) eine Liste der Kinder speichert, die von DragEvent benachrichtigt werden sollen. Darüber hinaus wird dieser Cache nur gefüllt, wenn ACTION_DRAG_STARTED empfangen wird. Weitere Informationen finden Sie im Quellcode hier .

Weiter zur Lösung! Anstatt auf Drop-Events in den einzelnen Zeilen von ListView zu warten, hören wir sie auf ListView selbst. Basierend auf den Koordinaten der Ereignisse werden wir dann herausfinden, in welche Zeile die gezogene Ansicht gezogen wird oder über die sie gezogen wird. Wenn der Fall eintritt, führen wir die Transaktion aus, die aus der vorherigen Zeile entfernt und zur neuen Zeile hinzugefügt wird.

%Vor%

Viele Kommentare, so hoffentlich ist der Code selbstdokumentierend. Ein paar Anmerkungen:

  • RandomIconAdapter ist nur ein einfacher Adapter, der BaseAdapter erweitert und von sIconsForListItems unterstützt wird.
  • ListViewScrollingDragListener ist identisch mit dem in der Eingabeaufforderung.
  • Getestet auf GS6 5.0.2
Trevor Carothers 21.07.2015, 05:26
quelle