Kommentare - Eine Android App für die Steem Blockchain - Teil #34
Beim Überlegen, was eine App für Steem braucht, ist mir eine Sache eingefallen, die ich bisher überhaupt nicht bedacht habe: Kommentare. Kommentare sind ein sehr wichtiger Bestandteil und sollen deshalb auch in der App vertreten sein. Jeder Kommentar wird zusammen mit Name des Autors und dessen Profilbild, sowie darunter mit den klassischen Upvote Infos (Status/Upvotebutton, Upvotezahl und Wert der Upvotes/Rewards) angezeigt. Ein Tipp auf den Nutzernamen soll zum entsprechenden Profil führen. Eines der größten Probleme bei Kommentaren ist aber die Verschachtelung, d.h. dass ein Post x Kommentare hat, die aber jeweils wieder x Unterkommentare haben, die dann wieder x Unterkommentare haben können, usw. Es liegt also nahe, dass sich dieses Szenario am besten Rekursiv lösen lässt, d.h. dass die Kommentare immer weiter geladen werden, bis ein Kommentar keine weitern Unterkommentare hat. Das aktuelle Problem daran ist aber die sehr schlechte Performence, da ich noch am probieren bin, wie das Laden der Kommentare in extra Threads verschoben werden kann. Aktuell möchte ich nur berichten, wie die Kommentare geladen und angezeigt werden.
Layouts
Zunächst ist im Layout der Activity für die Postansicht ein zuätzliches LinearLayout hinzuzufügen. Ich habe zusätzlich noch einen Titel ("Comments"/"Kommentare") und eine Information das keine Kommentare vorhanden sind ("No Comments"/"Keine Kommentare") hinzugefügt. Das Layout sieht so aus:
(Layoutbaum)
(Vorschau)
Diesem LinearLayout werden die einzelnen Kommentare (oberste Ebene) hinzugefügt. Diese werden aus einer weiteren Layoutdatei generiert, die die oben genannten Merkmale für Kommentare aufweist. Zusätzlich gibt es auch hier wieder ein LinearLayout für Unterkommentare. Dieses Layout sieht so aus:
API
Nun müssen die Kommentare noch geladen werden. Ich benutze wie immer die SteemJS REST API von SteemConnect und die dazugehörige Methode getContentReplies. Diese gibt alle Kommentare unter einem Post oder Kommentar als JSONArray zurück. Der dazugehörige Quellcode ist folgender:
Laden ins "Post" Objekt
Die Posts werden in Form von Objekten gespeichert. Diese Objekte können eine Post ArrayList speichern. Effektiv ist also jeder Kommentar ein Post. Die Kommentare müssen ihrem Parent aber hinzugefügt werden. Das geschieht in der jsonToPosts, bzw. jsonToPost Methode im JsonConverter. Dazu wird in dieser Methode eine weitere Methode "loadComments" aufgerufen, wenn der JSON-Block zum aktuellen Post "children" hat. "children" ist eine Ganzzahl, die die Zahl der Kommentare angibt. Ist sie größer als 0, gibt es Kommentare. Daraus ergibt sich folgender Aufruf:
Die aufgerufene Methode führt im Prinzip nur die jsonToPosts Methode wieder aus, diesmal wird aber anstelle der getContent Methode zum Abrufen von Posts die getContentReplies Methode aufgerufen. Hier ergibt sich also die Rekursion zum Laden der Kommentare aus der Blockchain. Im folgenden die Methode:
Geladen sind die Kommentare schon, fehlt noch das Anzeigen:
Anzeigen der Kommentare
Um die Kommentare anzuzeigen wird nach dem Setzten der Postfelder eine Methode aufgerufen, die das Hinzufügen aller Kommentare eines Posts zu einem LinearLayout übernimmt. Diese wird zum ersten Mal so aufgerufen:
Die Methode selbst überprüft zunächst, ob der Post Kommentare hat. Ist dies nicht der Fall, wird sie Beendet und das Ende der Rekursion ist erreicht. Gibt es aber Kommentare, werden dieser der Reihe nach einzeln Abgerufen und dem Layout hinzugefügt. Am Ende wird für jeden Kommentar erneut die Methode zum Kommentarehinzufügen aufgerufen. Die gesamte Methode sieht so aus:
(Teil 1)
(Teil 2)
Ergebnis
Am Ende ist es Zeit, das Ergebnis anzusehen. Wie oben schon erwähnt, hat das Laden lange gedauert (ca. 15 Sekunden), was natürlich noch viel zu lange ist. Die lange Ladezeit kommt daher, dass beim Appstart die letzten 10 Posts des Feeds mit allen Kommentaren geladen werden. Hier möchte ich später mit mehreren Threads die Performence deutlich verbessern. Aber zunächst reicht ein Blick auf folgenden Screenshot um zu sehen, dass alles funktioniert hat:
Kommentare werden nun also auch endlich angezeigt!