Derzeit ist keine Standardimplementierung von RecyclerView.Adapter verfügbar.
Möglicherweise mit der offiziellen Veröffentlichung, wird Google es hinzufügen.
Da gibt es keine Unterstützung für CursorAdapter
mit der RecyclerView
Zeit, wie können wir eine Verwendung RecyclerView
mit einer Datenbank? Irgendwelche Vorschläge ?
android
simplecursoradapter
android-recyclerview
Verlorenes Hündchen
quelle
quelle
setHasStableIds(true)
Meine Lösung bestand darin, ein CursorAdapter-Mitglied in meiner recyclerView.Adapter-Implementierung zu halten. Übergeben Sie dann die gesamte Behandlung zum Erstellen der neuen Ansicht und zum Binden an den Cursoradapter.
quelle
public void changeCursor(Cursor cursor){ mCursorAdapter.changeCursor(cursor); notifyDataSetChanged(); }
Da Ihre Frage "Verwendung
RecyclerView
mit einer Datenbank" lautet und Sie nicht genau wissen, ob Sie SQLite oder etwas anderes mit dem möchtenRecyclerView
, gebe ich Ihnen eine Lösung, die sehr optimal ist. Ich werde Realm als Datenbank verwenden und Sie alle Daten in Ihrem anzeigen lassenRecyclerView
. Es unterstützt auch asynchrone Abfragen, ohneLoaders
oder zu verwendenAsyncTask
.Warum Reich?
Schritt 1
Fügen Sie die Gradle-Abhängigkeit für Realm hinzu. Die Abhängigkeit für die neueste Version finden Sie hier
Schritt 2
Wenn Sie beispielsweise Ihre Modellklasse erstellen, können Sie beispielsweise
Data
zwei Felder, eine Zeichenfolge, die in derRecyclerView
Zeile angezeigt werden soll, und einen Zeitstempel verwenden, der als itemId zum Animieren vonRecyclerView
Elementen verwendet wird. Beachten Sie, dass ich weiterRealmObject
unten erläutere, weshalb IhreData
Klasse als Tabelle und alle Ihre Eigenschaften als Spalten dieser Tabelle gespeichert werdenData
. Ich habe den Datentext in meinem Fall als Primärschlüssel markiert, da ich nicht möchte, dass eine Zeichenfolge mehr als einmal hinzugefügt wird. Wenn Sie jedoch Duplikate bevorzugen, legen Sie den Zeitstempel als @PrimaryKey fest. Sie können eine Tabelle ohne Primärschlüssel haben, dies kann jedoch zu Problemen führen, wenn Sie versuchen, die Zeile nach dem Erstellen zu aktualisieren. Ein zusammengesetzter Primärschlüssel zum Zeitpunkt des Schreibens dieser Antwort wird von Realm nicht unterstützt.Schritt 3
Erstellen Sie Ihr Layout dafür, wie eine einzelne Zeile in der angezeigt werden soll
RecyclerView
. Das Layout für ein einzelnes Zeilenelement in unseremAdapter
ist wie folgtBeachten Sie, dass ich eine
FrameLayout
als Wurzel behalten habe , obwohl ich eineTextView
innere habe. Ich habe vor, weitere Elemente in dieses Layout aufzunehmen und es daher vorerst flexibel zu gestalten :)Für die Neugierigen da draußen sieht ein einzelner Artikel derzeit so aus.
Schritt 4
Erstellen Sie Ihre
RecyclerView.Adapter
Implementierung. In diesem Fall ist das Datenquellenobjekt ein spezielles Objekt,RealmResults
das als LIVE bezeichnetArrayList
wird. Mit anderen Worten, wenn Elemente zu Ihrer Tabelle hinzugefügt oder daraus entfernt werden, wird diesesRealmResults
Objekt automatisch aktualisiert.Beachten Sie, dass ich
notifyItemRemoved
mit der Position anrufe, an der die Entfernung stattgefunden hat, aber NICHT anrufenotifyItemInserted
odernotifyItemRangeChanged
weil es keine direkte Möglichkeit gibt, festzustellen, an welcher Position das Element in die Datenbank eingefügt wurde, da Realm-Einträge nicht in geordneter Weise gespeichert werden. DasRealmResults
Objekt wird automatisch aktualisiert, wenn ein neues Element hinzugefügt, geändert oder aus der Datenbank entfernt wird, sodass wirnotifyDataSetChanged
beim Hinzufügen und Einfügen von Masseneinträgen aufrufen . An diesem Punkt sind Sie wahrscheinlich besorgt über die Animationen, die nicht ausgelöst werden, weil SienotifyDataSetChanged
anstelle vonnotifyXXX
Methoden aufrufen . Genau deshalb muss diegetItemId
Methode den Zeitstempel für jede Zeile aus dem Ergebnisobjekt zurückgeben. Die Animation erfolgt in 2 Schritten mit,notifyDataSetChanged
wenn Sie anrufensetHasStableIds(true)
und dann überschreibengetItemId
etwas anderes als nur die Position zu bieten.Schritt 5
Fügen
RecyclerView
wir das zu unseremActivity
oder hinzuFragment
. In meinem Fall verwende ich eineActivity
. Die Layoutdatei mit demRecyclerView
ist ziemlich trivial und würde ungefähr so aussehen.Ich habe eine hinzugefügt,
app:layout_behavior
seit ichRecyclerView
in eine gehe,CoordinatorLayout
die ich der Kürze halber in dieser Antwort nicht gepostet habe.Schritt 6
Konstruieren Sie den
RecyclerView
In-Code und geben Sie die benötigten Daten an. Erstellen und initialisieren Sie ein Realm-Objekt im InnerenonCreate
und schließen Sie es im Inneren,onDestroy
ähnlich wie beim Schließen einerSQLiteOpenHelper
Instanz. Im einfachsten Fall sieht IhronCreate
InneresActivity
so aus. DieinitUi
Methode ist, wo all die Magie passiert. Ich öffne eine Instanz von Realm im InnerenonCreate
.Beachten Sie, dass ich im ersten Schritt Realm abfrage, um mir alle Objekte aus der
Data
Klasse zu geben, die asynchron nach ihrem Variablennamen namens data sortiert sind. Dies gibt mir einRealmResults
Objekt mit 0 Elementen im Hauptthread, das ich auf dem einstelleAdapter
. Ich habe ein hinzugefügtRealmChangeListener
, um benachrichtigt zu werden, wenn das Laden der Daten aus dem Hintergrund-Thread, in dem ichnotifyDataSetChanged
mit meinem aufrufe, abgeschlossen istAdapter
. Ich habe auchsetHasStableIds
true aufgerufen , damit dieRecyclerView.Adapter
Implementierung Elemente verfolgt, die hinzugefügt, entfernt oder geändert wurden. DasonDestroy
für michActivity
schließt die Realm-InstanzDiese Methode
initUi
kann inonCreate
IhremActivity
oderonCreateView
oderonViewCreated
von Ihrem aufgerufen werdenFragment
. Beachten Sie die folgenden Dinge.Schritt 7
BAM! Es gibt Daten aus der Datenbank in Ihrem
RecyclerView
asynchonously ohne geladenCursorLoader
,CursorAdapter
,SQLiteOpenHelper
mit Animationen. Das hier gezeigte GIF-Bild ist etwas verzögert, aber die Animationen werden ausgeführt, wenn Sie Elemente hinzufügen oder entfernen.quelle
Sie können alle erforderlichen Methoden selbst implementieren. Ich habe kürzlich meine eigene Implementierung vorgenommen, indem ich einfach den Einfügecode von CursorAdapter kopiert habe.
quelle
Ich habe einen RecyclerViewCursorAdapter mit einer SortedList als Backend erstellt und RecyclerView.Adapter erweitert
Kann mit SQLiteCursor und Loadern verwendet werden
quelle
Nur eine weitere Antwort, da mir die akzeptierte nicht gefallen hat (was imo keine intuitive Verwendung hat).
Das Folgende ist meine eigene Implementierung, die sehr ähnlich ist (und teilweise davon inspiriert ist)
SimpleCursorAdapter
:Sie können es für andere bestimmte Verwendungszwecke ändern, aber mit einem Cursor funktioniert es genauso wie
SimpleCursorAdapter
nur mit aRecyclerView
.quelle
Nach dem Abrufen von Daten aus der Datenbank und dem Speichern in einer Liste sollte dies möglicherweise folgendermaßen aussehen:
Daten zu recyclerview hinzufügen
quelle
Unten ist meine Implementierung des Cursoradapters für eine Recycling-Ansicht. Es unterstützt OnItemClickListener, OnLongItemClickListener, OnfooterClickListener, Abschnitte und Fußzeile. Unterstützt nicht , Header, onHeaderClickListner, Fast Scroller, Sticky Header oder Sticky Abschnitte.
Erweitern Sie einfach diesen Adapter und erstellen Sie Ihren eigenen Adapter. Überschreiben Sie die bereitgestellten Methoden. und übergeben Sie den Cursor von der OnCursorLoadFinished-Methode. Wenn der Adapter bereits erstellt wurde, dann swapCursor ()
quelle
Die einfachste Implementierung besteht darin, das Cursorobjekt im Adapter zu verwenden und den Cursor an den Viewholder-Konstruktor zu übergeben, um Ansichten zu ändern und die Cursorposition in onBindViewholder zu ändern.
Wenn Sie den Cursor Loader verwenden, rufen Sie die setCursor-Methode auf
onLoadfinished()
und übergeben Sie nullonLoadReset()
}}
quelle
Endlich haben wir eine Implementierung von RecyclerView.Adapter für Datenbank / Netzwerk.
Es wurde mit einer Android- Architektur Komponenten realisiert :
Raumdatenbank: Datenbankebene über der SQLite-Datenbank, die sich um alltägliche Aufgaben kümmert, die Sie mit einem erledigt haben
SQLiteOpenHelper
. Datenbankhalter, der als Zugriffspunkt auf die zugrunde liegende SQLite-Datenbank dient. Die Room-Datenbank verwendet das DAO, um Abfragen an die SQLite-Datenbank zu senden.ViewModel: Stellt Daten für die Benutzeroberfläche bereit. Dient als Kommunikationszentrum zwischen dem Repository und der Benutzeroberfläche. Versteckt, woher die Daten von der Benutzeroberfläche stammen. ViewModel-Instanzen überleben die Wiederherstellung von Aktivitäten / Fragmenten.
LiveData: Eine Datenhalterklasse, die beobachtet werden kann. Hält / speichert immer die neueste Version der Daten. Benachrichtigt seine Beobachter, wenn sich die Daten geändert haben. LiveData ist lebenszyklusabhängig. UI-Komponenten beobachten nur relevante Daten und stoppen oder setzen die Beobachtung nicht fort. LiveData verwaltet all dies automatisch, da es die relevanten Änderungen des Lebenszyklusstatus während der Beobachtung kennt.
quelle
Sie können die SQLite-Datenbank verwenden, um die Details zu speichern. Der Zugriff auf die Daten ist einfach. Sie können meinen Code auf Github überprüfen. https://github.com/thiru-wta/ToDo
Datenbankmethoden:
Methode abrufen:
quelle
Sie müssen einfach die folgenden Schritte ausführen:
view.adapter
Erstellen Sie im Recycler eine ArrayList oder einen Iterator, der mit einem Nullwert initialisiert wurde.swapdata(Arraylist<T> data)
. Im Inneren geben Sie der Array-Liste, dem Iterator oder einer beliebigen Struktur, die das System mithilfe der Ganzzahlposition in der Bindungsansicht iterieren kann, neue Werte. Die Werte dieser Methode werden in der übergebenonloaderfinished()
. Rufen Sie dann gleich nach der Zuweisung annotifydatachange()
. Diese werdenRecyclerView
aufgefordert, die gesamte Liste mit neuen Daten der ArrayList neu zu zeichnen.Erstellen Sie in der Aktivität oder dem Fragment, in dem Sie den Loadercalback verwenden, eine Methode, die den Cursor abhängig von der im Adapter ausgewählten Datenstruktur in eine Arrayliste oder einen Iterator umwandelt.
Auf diese Weise können Sie den Loadercalback immer verwenden, ohne den Hauptthread zu blockieren.
quelle