Aufgaben-App: Nach rechts wischen

Aufgaben-App: Nach rechts wischen

Im letzten Video hatte ich dir gezeigt, wie man Aufgaben per Drag&Drop in der Liste sortieren kann. In diesem Video geht es darum, dass wir die Aufgaben nach rechts wischen können, um sie abzuhaken, also zu erledigen.

Wischen erlauben

Um das Wischen nach rechts zu erlauben, müssen wir zunächst in der TaskListTouchCallback-Klasse den Konstruktor so ändern, dass wir die erlaubte Richtung für das Wischen definieren.

super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT);

Hierfür nutzen wir die Konstante ItemTouchHelper.RIGHT.

Aufgabe entfernen

Um eine Aufgabe aus der Aufgabenliste zu entfernen, erweitern wir den TaskManager. Zwar haben wir schon eine Methode zum Löschen einer bestimmten Aufgabe, es wäre aber noch besser, wenn wir eine zweite Methode haben, um eine Aufgabe auch anhand ihrer aktuellen Position in der Liste zu löschen.

Also ergänzen wir im TaskManager:

Die TaskListTouchCallback-Klasse hat eine onSwipe-Methode, die im Moment noch leer ist. Diese Methode wird immer dann aufgerufen, wenn der Nutzer eine Aufgabe zur Seite wischt. Diese Methode müssen wir implementieren, weil wir ja in dem Moment, wo eine Aufgabe zur Seite gewischt wird, die entsprechende Aufgabe aus der Liste löschen wollen.

Wir ermitteln die Position der gewischten Aufgabe anhand des ViewHolders, den wir übergeben bekommen. Anschließend rufen wir die neue Methode unseres TaskManagers auf, um die Aufgabe zu entfernen. Und als letztes benachrichtigen wir den Adapter unserer RecyclerView, um die Ansicht zu aktualisieren. Dadurch wird eine kleine Animation gestartet und die Aufgabe tatsächlich aus der angezeigten Liste entfernt.

Die RecyclerView in der letzten Code-Zeile ist rot markiert. Das liegt daran, dass unsere TaskListTouchCallback-Klasse die RecyclerView gar nicht kennt. Um dieses Problem zu lösen, übergeben wir die RecyclerView im Konstruktor der Klasse, so wie wir das auch mit dem TaskManager machen.

Denk daran, dass nun auch die MainActivity angepasst werden muss. Wir übergeben die RecyclerView an die TaskListTouchCallback-Klasse:

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TaskListTouchCallback(taskManager, recyclerView));

Pro-Variante: Adapter nutzen

Soweit so gut, das wird funktionieren. Allerdings gibt es noch eine zweite Variante, die eleganter ist. Die zeig ich dir jetzt!

Wir können vermeiden die RecyclerView an die TaskListTouchCallback-Klasse zu übergeben, indem wir den Adapter nutzen, denn eigentlich wollen wir ja lediglich die notify-Methoden des Adapters aufrufen. Und das geht eben einfacher.

Dazu übergeben wir an die TaskListTouchCallback-Klasse weder den TaskManager, noch die RecyclerView, sondern lediglich den TaskListAdapter. Das genügt völlig, wirst du gleich sehen. Der Konstruktor der TaskListTouchCallback-Klasse sieht dann so aus:

Da wir den Konstruktor geändert haben, müssen wir auch die Instanziierung in der MainActivity entsprechend wieder anpassen. Das sieht dann in der MainActivity so aus, und zwar in der initViews-Methode:

TaskListAdapter taskListAdapter = new TaskListAdapter(taskManager);
recyclerView.setAdapter(taskListAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new TaskListTouchCallback(taskListAdapter));

Wir instanziieren den Adapter in einer separaten Zeile, um ihn einer lokalen Variablen zuzuweisen. Diese lokale Variable übergeben wir einerseits an die RecyclerView, damit sie weiß, welchen Adapter sie verwenden soll. Und andererseits übergeben wir die lokale Variable an unseren TaskListTouchCallback.

Als nächstes müssen wir den Adapter anpassen. Wir brauchen zwei Methoden: Die eine, um eine Aufgabe umzusortieren, also in der Liste zu verschieben. Und die andere, um eine Aufgabe anhand ihrer Position zu löschen. Das sieht dann im TaskListAdapter so aus:

Die onCheckedChange-Methode ist kürzer geworden, weil wir dort nur noch removeTask aufrufen. Warum? Ganz einfach, weil wir die removeTask-Methode gleich wiederverwenden werden. Denn es ist egal, ob der Nutzer eine Aufgabe mit der Checkbox ganz normal abhakt, oder die Aufgabe nach rechts wischt, um sie zu erledigen. In beiden Fällen soll dasselbe passieren: Die Aufgabe soll aus der Liste gelöscht werden.

Beachte, dass removeTask und moveTask öffentliche Methoden sein müssen, weil wir sie aus einer anderen Klasse aufrufen wollen. Daher verwenden wir hier das Schlüsselwort public.

Nun passen wir die TaskListTouchCallback-Klasse entsprechend an:

Wir überarbeiten die onMove-Methode und auch die onSwiped-Methode. Hier rufen wir jeweils die richtige Methode im TaskListAdapter auf. Dadurch wird unsere Klasse recht schlank und übersichtlich.

Fertig! Das ist die Pro-Variante. Erkennst du den Unterschied im Code? Welche Variante findest du besser?