Ich habe eine Liste von Datensätzen in einer Listenansicht, die der Benutzer per Drag-and-Drop-Methode neu sortieren kann. Ich habe gesehen, dass dies in anderen Apps implementiert ist, aber ich habe kein Tutorial dafür gefunden. Es muss etwas sein, was andere auch brauchen. Kann mir jemand einen Code dafür zeigen?
Android-Listenansicht Drag-and-Drop-Sortierung
heycosmo
Daran arbeite ich schon seit einiger Zeit. Es ist schwierig, es richtig zu machen, und ich behaupte nicht, dass ich es tue, aber ich bin bisher zufrieden damit. Meinen Code und mehrere Demos finden Sie unter
Seine Verwendung ist dem TouchInterceptor (auf dem der Code basiert) jedoch sehr ähnlich von Bedeutung Implementierungsänderungen vorgenommen wurden.
DragSortListView bietet ein reibungsloses und vorhersagbares Scrollen beim Ziehen und Mischen von Elementen. Das Mischen von Gegenständen stimmt viel besser mit der Position des gezogenen/schwebenden Gegenstands überein. Listenelemente mit heterogener Höhe werden unterstützt. Drag-Scrolling ist anpassbar (ich demonstriere schnelles Drag-Scrolling durch eine lange Liste – nicht, dass mir eine Anwendung in den Sinn kommt). Kopf-/Fußzeilen werden berücksichtigt. etc.?? Schau mal.
-
Ihre Lösung funktioniert wie ein Zauber. Viel besser als andere. Was ist die Lizenz Ihres Quellcodes? Apache 2.0?
– Dariusz Bacinski
3. Juli 12 um 7:56 Uhr
-
@heycosmo Ich habe ein paar Probleme beim Erstellen eines Layouts in meiner App mit den in der Demo bereitgestellten Ansichten. Mehrere Namensraumfehler, könnten Sie bitte vielleicht einen kleinen Blogpost darüber schreiben, wie Sie den von Ihnen bereitgestellten Code verwenden?
– daniel_c05
11. Februar 13 um 18:24 Uhr
-
Gibt es eine Möglichkeit, den Code so zu ändern, dass Artikel nicht nur beim Herunterfallen sortiert werden, während Sie Ihren Artikel darüber ziehen?
– Alex Semenjuk
26. März 13 um 13:43 Uhr
-
@heycosmo Können Sie Ihr GitHub-Repository zugänglich machen? Scheint offline zu sein…
– sdasdadas
12. Mai ’13 um 1:41 Uhr
-
Das bauerca-Repo wird nicht mehr gepflegt. Diese Gabel ist aktiver: github.com/JayH5/drag-sort-listview
– ecdpalma
30. März 15 um 20:01 Uhr
Jetzt ist es ziemlich einfach zu implementieren für RecyclerView
mit ItemTouchHelper. Einfach überschreiben onMove
Methode aus ItemTouchHelper.Callback
:
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
mMovieAdapter.swap(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
Ein ziemlich gutes Tutorial dazu finden Sie auf medium.com: Ziehen und wischen Sie mit RecyclerView
Arrun C
Ich füge diese Antwort für diejenigen hinzu, die darüber googeln.
Es gab eine Episode von DevBytes (Ziehen und Neuanordnen von ListView-Zellen) kürzlich erklärt, wie das geht
Du kannst es finden Hier auch der Beispielcode ist verfügbar Hier.
Was dieser Code im Grunde tut, ist, dass er eine erstellt dynamic listview
durch die Verlängerung von listview
das das Ziehen und Austauschen von Zellen unterstützt. Damit Sie die verwenden können DynamicListView
anstelle Ihrer Basis ListView
und schon haben Sie eine ListView mit Drag and Drop implementiert.
-
Denken Sie bei der Verwendung der DevBytes-Implementierung daran, dass Ihr Adapter und DynamicListView Mush dieselbe Instanz des Objektarrays gemeinsam nutzen. Sonst funktioniert die Umsetzung nicht. Dies ist kein Problem für statische Listen, kann aber bei Loadern eine Herausforderung darstellen
– AAverin
12. Januar 14 um 9:51 Uhr
-
Ich habe das Beispiel auf einer aktuellen Android-Version 5.0 ausprobiert. Es hat jetzt einige Probleme …
– Thorsten B
7. Januar 15 um 9:16 Uhr
-
@TCA Ja, ich habe auch Probleme mit 5.0. Bitte helfen Sie.
– Manuel
16. April 15 um 14:07 Uhr
Die DragListView-Bibliothek macht das wirklich ordentlich mit sehr netter Unterstützung für benutzerdefinierte Animationen wie Höhenanimationen. Es wird auch weiterhin gepflegt und regelmäßig aktualisiert.
So verwenden Sie es:
1: Fügen Sie zuerst die Lib zu Gradle hinzu
dependencies {
compile 'com.github.woxthebox:draglistview:1.2.1'
}
2: Liste aus XML hinzufügen
<com.woxthebox.draglistview.DragListView
android:id="@+id/draglistview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
3: Legen Sie den Drag-Listener fest
mDragListView.setDragListListener(new DragListView.DragListListener() {
@Override
public void onItemDragStarted(int position) {
}
@Override
public void onItemDragEnded(int fromPosition, int toPosition) {
}
});
4: Erstellen Sie einen Adapter, der von DragItemAdapter überschrieben wird
public class ItemAdapter extends DragItemAdapter<Pair<Long, String>, ItemAdapter.ViewHolder>
public ItemAdapter(ArrayList<Pair<Long, String>> list, int layoutId, int grabHandleId, boolean dragOnLongPress) {
super(dragOnLongPress);
mLayoutId = layoutId;
mGrabHandleId = grabHandleId;
setHasStableIds(true);
setItemList(list);
}
5: Implementieren Sie einen Viewholder, der sich von DragItemAdapter.ViewHolder erstreckt
public class ViewHolder extends DragItemAdapter.ViewHolder {
public TextView mText;
public ViewHolder(final View itemView) {
super(itemView, mGrabHandleId);
mText = (TextView) itemView.findViewById(R.id.text);
}
@Override
public void onItemClicked(View view) {
}
@Override
public boolean onItemLongClicked(View view) {
return true;
}
}
Weitere Informationen finden Sie unter https://github.com/woxblom/DragListView
Eduard Brey
ich fand DragSortListView funktionierte gut, obwohl der Einstieg hätte einfacher sein können. Hier ist ein kurzes Tutorial zur Verwendung in Android Studio mit einer In-Memory-Liste:
-
Fügen Sie dies hinzu
build.gradle
Abhängigkeiten für Ihre App:compile 'asia.ivity.android:drag-sort-listview:1.0' // Corresponds to release 0.6.1
-
Erstellen Sie eine Ressource für die Ziehgriff-ID, indem Sie erstellen oder hinzufügen
values/ids.xml
:<resources> ... possibly other resources ... <item type="id" name="drag_handle" /> </resources>
-
Erstellen Sie ein Layout für ein Listenelement, das Ihr bevorzugtes Ziehgriffbild enthält, und weisen Sie seine ID der ID zu, die Sie in Schritt 2 erstellt haben (z
drag_handle
). -
Erstellen Sie ein DragSortListView-Layout, etwa so:
<com.mobeta.android.dslv.DragSortListView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dslv="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" dslv:drag_handle_id="@id/drag_handle" dslv:float_background_color="@android:color/background_light"/>
-
Setze ein
ArrayAdapter
Ableitung mit agetView
überschreiben, die Ihre Listenelementansicht rendert.final ArrayAdapter<MyItem> itemAdapter = new ArrayAdapter<MyItem>(this, R.layout.my_item, R.id.my_item_name, items) { // The third parameter works around ugly Android legacy. http://stackoverflow.com/a/18529511/145173 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); MyItem item = getItem(position); ((TextView) view.findViewById(R.id.my_item_name)).setText(item.getName()); // ... Fill in other views ... return view; } }; dragSortListView.setAdapter(itemAdapter);
-
Legen Sie einen Drop-Listener fest, der die Elemente beim Löschen neu anordnet.
dragSortListView.setDropListener(new DragSortListView.DropListener() { @Override public void drop(int from, int to) { MyItem movedItem = items.get(from); items.remove(from); if (from > to) --from; items.add(to, movedItem); itemAdapter.notifyDataSetChanged(); } });
DarkCygnus
Ich bin vor kurzem über diese tolle gestolpert Kern das gibt eine funktionierende Implementierung einer Drag-Sortierung ListView
ohne dass externe Abhängigkeiten erforderlich sind.
Grundsätzlich besteht es darin, Ihre benutzerdefinierte Adaptererweiterung zu erstellen ArrayAdapter
als innere Klasse zu der Aktivität, die Ihre enthält ListView
. Auf diesen Adapter legt man dann einen an onTouchListener
zu Ihren Listenelementen, die den Beginn des Ziehens signalisieren.
In diesem Gist setzen sie den Zuhörer auf einen bestimmten Teil des Layouts des Listenelements (den “Griff” des Elements), sodass man es nicht versehentlich bewegt, indem man auf einen Teil davon drückt. Ich persönlich bevorzuge es, mit einem zu gehen onLongClickListener
stattdessen, aber das liegt an Ihnen zu entscheiden. Hier ein Auszug aus diesem Teil:
public class MyArrayAdapter extends ArrayAdapter<String> {
private ArrayList<String> mStrings = new ArrayList<String>();
private LayoutInflater mInflater;
private int mLayout;
//constructor, clear, remove, add, insert...
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View view = convertView;
//inflate, etc...
final String string = mStrings.get(position);
holder.title.setText(string);
// Here the listener is set specifically to the handle of the layout
holder.handle.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
startDrag(string);
return true;
}
return false;
}
});
// change color on dragging item and other things...
return view;
}
}
Dazu gehört auch das Hinzufügen eines onTouchListener
zum ListView
, die überprüft, ob ein Element gezogen wird, das Austauschen und Ungültigmachen handhabt und den Ziehzustand stoppt. Ein Auszug aus diesem Teil:
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (!mSortable) { return false; }
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
break;
}
case MotionEvent.ACTION_MOVE: {
// get positions
int position = mListView.pointToPosition((int) event.getX(),
(int) event.getY());
if (position < 0) {
break;
}
// check if it's time to swap
if (position != mPosition) {
mPosition = position;
mAdapter.remove(mDragString);
mAdapter.insert(mDragString, mPosition);
}
return true;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE: {
//stop drag state
stopDrag();
return true;
}
}
return false;
}
});
Schließlich ist hier, wie die stopDrag
und startDrag
Methoden aussehen, die das Aktivieren und Deaktivieren des Ziehvorgangs behandeln:
public void startDrag(String string) {
mPosition = -1;
mSortable = true;
mDragString = string;
mAdapter.notifyDataSetChanged();
}
public void stopDrag() {
mPosition = -1;
mSortable = false;
mDragString = null;
mAdapter.notifyDataSetChanged();
}
ueen
Ich baue eine neue Bibliothek basierend auf RecyclerView, check it out
Sehen Sie sich meine neue Bibliothek für diese Aufgabe an
https://github.com/ueen/SortView/
.
Ich habe dieses Tutorial gefunden, das helfen könnte Erstellen einer sortierbaren Listenansicht. Ich habe es noch nicht getestet, aber das Video sieht vielversprechend aus
– Alex
6. September 12 um 18:11 Uhr
@ Arkde kein Scherz, sie haben Jahre später immer noch keine Antwort auf diese Frage akzeptiert.
– ArtOfWarfare
10. Oktober 12 um 17:37 Uhr
@ArtOfWarfare Ich denke, man sollte bedenken, dass dem Fragesteller etwas Unglückliches passiert sein könnte … was weitere Aktivitäten verbietet.
– heycosmo
11. November 12 um 22:12 Uhr
@heycosmo Es ist möglich … laut ihrem SO-Profil war miannelle zuletzt nur einen Monat nach dem Stellen der Frage zu Besuch. Außerdem großartige Arbeit am DSLV … Ich habe ein paar Änderungen daran vorgenommen, um Dinge wie Doppeltippen zum Duplizieren von Elementen und Ändern des Schattens des Elements beim Herumziehen zu ermöglichen (meine Elemente haben jeweils ihre Zeilennummer darauf, also ich Ich habe es so gemacht, dass die Zeilennummernaktualisierungen beim Ziehen aktualisiert werden können.) Sie sind irgendwie nur gehackt, weit weniger elegant als alles andere in der Klasse, weshalb ich die Änderungen nicht an GitHub übermittelt habe.
– ArtOfWarfare
12. November 12 um 4:07 Uhr
github.com/bauerca/drag-sort-listview Ich verwende dies und ist es möglich, eine REIHE onLongClick von Listview zu ziehen?
– Achin
9. Februar 15 um 12:33 Uhr