Paging 2-Bibliothek – Übersicht Teil von Android Jetpack
Mit der Paging Library können Sie kleine Datenblöcke gleichzeitig laden und anzeigen. Das Laden von Teildaten bei Bedarf reduziert die Nutzung von Netzwerkbandbreite und System Ressourcen.
Dieser Leitfaden enthält mehrere konzeptionelle Beispiele der Bibliothek sowie eine einen Überblick über die Funktionsweise. Um vollständige Beispiele dafür anzuzeigen, wie diese Bibliothek testen Sie das Codelab und Beispiele aus den zusätzlichen Ressourcen.
Einrichten
Fügen Sie Folgendes hinzu, um Paging-Komponenten in Ihre Android-App zu importieren
zur Datei build.gradle
Ihrer Anwendung hinzufügen:
Cool
dependencies { def paging_version = "2.1.2" implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-ktx // alternatively - without Android dependencies for testing testImplementation "androidx.paging:paging-common:$paging_version" // For Kotlin use paging-common-ktx // optional - RxJava support implementation "androidx.paging:paging-rxjava2:$paging_version" // For Kotlin use paging-rxjava2-ktx }
Kotlin
dependencies { val paging_version = "2.1.2" implementation("androidx.paging:paging-runtime:$paging_version") // For Kotlin use paging-runtime-ktx // alternatively - without Android dependencies for testing testImplementation("androidx.paging:paging-common:$paging_version") // For Kotlin use paging-common-ktx // optional - RxJava support implementation("androidx.paging:paging-rxjava2:$paging_version") // For Kotlin use paging-rxjava2-ktx }
Bibliotheksarchitektur
In diesem Abschnitt werden die Hauptkomponenten der Paging-Bibliothek beschrieben und dargestellt.
Seitenliste
Die Hauptkomponente der Paging Library
Klasse PagedList
, die geladen wird
Teile Ihrer App-Daten oder Seiten. Da mehr Daten benötigt werden,
das vorhandene PagedList
-Objekt aufgerufen wird. Wenn sich geladene Daten ändern, wird ein neuer
Instanz von PagedList
an den Inhaber der beobachtbaren Daten von einer
LiveData
- oder RxJava2-basiertes Objekt. Als
PagedList
-Objekte generiert werden,
werden die Inhalte in der Benutzeroberfläche Ihrer App präsentiert.
Lebenszyklen.
Im folgenden Code-Snippet sehen Sie, wie Sie das Ansichtsmodell Ihrer App so konfigurieren können,
Daten mit dem Inhaber LiveData
von PagedList
-Objekten laden und präsentieren:
Kotlin
class ConcertViewModel(concertDao: ConcertDao) : ViewModel() { val concertList: LiveData<PagedList<Concert>> = concertDao.concertsByDate().toLiveData(pageSize = 50) }
Java
public class ConcertViewModel extends ViewModel { private ConcertDao concertDao; public final LiveData<PagedList<Concert>> concertList; // Creates a PagedList object with 50 items per page. public ConcertViewModel(ConcertDao concertDao) { this.concertDao = concertDao; concertList = new LivePagedListBuilder<>( concertDao.concertsByDate(), 50).build(); } }
Daten
Jede Instanz von PagedList
wird geladen.
eine aktuelle Übersicht der Daten Ihrer App aus der zugehörigen
DataSource
-Objekt. Datenflüsse
aus dem Back-End oder der Datenbank Ihrer App in das PagedList
-Objekt.
Im folgenden Beispiel wird die Funktion Raumpersistenz Bibliothek zum Organisieren der App-Daten verwenden. Ihre Daten auf andere Weise speichern möchten, können Sie auch Ihre eigenen Daten bereitstellen. Source Factory erstellt werden.
Kotlin
@Dao interface ConcertDao { // The Int type parameter tells Room to use a PositionalDataSource object. @Query("SELECT * FROM concerts ORDER BY date DESC") fun concertsByDate(): DataSource.Factory<Int, Concert> }
Java
@Dao public interface ConcertDao { // The Integer type parameter tells Room to use a // PositionalDataSource object. @Query("SELECT * FROM concerts ORDER BY date DESC") DataSource.Factory<Integer, Concert> concertsByDate(); }
Weitere Informationen zum Laden von Daten in PagedList
-Objekte findest du in der
Weitere Informationen zum Laden von Seitendaten
UI
Die Klasse PagedList
funktioniert mit einem
PagedListAdapter
, um Elemente in eine
RecyclerView
Diese
Klassen arbeiten zusammen, um Inhalte abzurufen und anzuzeigen, während sie geladen werden.
und animierte Inhalte ändern.
Weitere Informationen finden Sie unter Seitenumbruch Listen enthalten.
Verschiedene Datenarchitekturen unterstützen
Die Paging Library unterstützt die folgenden Datenarchitekturen:
- Sie werden nur von einem Backend-Server bereitgestellt.
- Wird nur in einer Datenbank auf dem Gerät gespeichert.
- Eine Kombination aus den anderen Quellen, wobei die Datenbank auf dem Gerät als Cache verwendet wird.
Abbildung 1 zeigt den Datenfluss in jedem dieser Architekturszenarien. In Bei einer reinen Netzwerk- oder Datenbanklösung fließen die Daten direkt das UI-Modell Ihrer App. Bei einem kombinierten Ansatz fließen Daten von Ihrem Back-End-Server, in eine Datenbank auf dem Gerät und dann in das UI-Modell Ihrer App. Hin und wieder gehen am Endpunkt jedes Datenflusses keine Daten zum Laden aus. und fordert dann mehr Daten von der Komponente an, die die Daten bereitgestellt hat. Wenn beispielsweise eine Datenbank auf dem Gerät keine Daten mehr hat, fordert sie mehr Daten an. vom Server.
Im weiteren Verlauf dieses Abschnitts finden Sie Empfehlungen für die Data Flow-Anwendungsfall.
Nur Netzwerk
Um Daten von einem Back-End-Server anzuzeigen, verwenden Sie die synchrone Version des
Retrofit API zum Laden
Informationen in Ihre eigene DataSource
.
Nur Datenbank
RecyclerView
einrichten
die lokale Speicherung beobachten, vorzugsweise mit der Funktion Raumpersistenz
Mediathek. Auf diese Weise, wenn Daten
in die Datenbank Ihrer App eingefügt oder
geändert haben, werden diese Änderungen
in der RecyclerView
wider, in der diese Daten angezeigt werden.
Netzwerk und Datenbank
Nachdem Sie begonnen haben, die Datenbank zu beobachten, können Sie darauf warten, wann die Datenbank
Datenbank keine Daten mehr hat,
PagedList.BoundaryCallback
Sie können dann weitere Elemente aus Ihrem Netzwerk abrufen und diese in den
Datenbank. Wenn Ihre Benutzeroberfläche die Datenbank beobachtet, ist das alles, was Sie tun müssen.
Netzwerkfehler beheben
Wenn Sie die angezeigten Daten mithilfe eines Netzwerks abrufen oder durch Paging Library, ist es wichtig, das Netzwerk nicht als „Verfügbar“ oder „nicht verfügbar“ da viele Verbindungen unterbrochen sind. unzuverlässig:
- Ein bestimmter Server kann unter Umständen nicht auf eine Netzwerkanfrage antworten.
- Das Gerät ist möglicherweise mit einem langsamen oder schwachen Netzwerk verbunden.
Stattdessen sollte Ihre Anwendung jede Anfrage auf Fehler prüfen und eine Wiederherstellung wenn das Netzwerk nicht verfügbar ist. Beispiel: können Sie eine Wiederholung Schaltfläche, über die Nutzer auswählen können, ob der Schritt nicht funktioniert. Tritt beim Datenpaging ein Fehler auf, versuchen Sie es am besten, die Paginganfragen automatisch verarbeiten.
Vorhandene App aktualisieren
Wenn Ihre App bereits Daten aus einer Datenbank oder einer Back-End-Quelle nutzt, ist es ein direktes Upgrade auf die Funktionen der Paging Library möglich ist. In diesem Abschnitt wird beschrieben, wie Sie eine App mit einem gängigen bestehenden Design aktualisieren.
Benutzerdefinierte Paging-Lösungen
Wenn Sie benutzerdefinierte Funktionen zum Laden kleiner Teilmengen von Daten aus dem
Datenquelle enthalten, können Sie diese Logik durch die
Klasse PagedList
. Instanzen von
PagedList
bieten integrierte Verbindungen zu gängigen Datenquellen. Diese Instanzen
bieten auch Adapter für
RecyclerView
-Objekte, die
die Sie in die Benutzeroberfläche Ihrer App einbinden können.
Daten, die mithilfe von Listen statt Seiten geladen werden
Wenn Sie eine Liste im Speicher als Sicherungsdatenstruktur für die
sollten Sie Datenaktualisierungen mit einem
Klasse PagedList
, wenn die Nummer
von Elementen in der Liste werden kann. Instanzen von PagedList
können Folgendes verwenden:
LiveData<PagedList>
oder
Observable<List>
, um Datenaktualisierungen an die Benutzeroberfläche deiner App zu übergeben und so die Ladezeiten zu minimieren
und Arbeitsspeichernutzung. Noch besser: Als Ersatz für List
PagedList
-Objekts in Ihrer App erfordert keine Änderungen an Ihrem
die UI-Struktur
oder die Logik der Datenaktualisierung der App.
Datencursor über CursorAdapter mit einer Listenansicht verknüpfen
Deine App verwendet möglicherweise einen CursorAdapter
um Daten aus einer Cursor
mit einem
ListView
In diesem Fall müssen Sie
von einem ListView
zu einem
RecyclerView
als Ihr
App-Liste und ersetzen Sie dann Cursor
mit entweder Room oder
PositionalDataSource
, je nachdem, ob Instanzen von Cursor
auf
SQLite-Datenbank.
In einigen Situationen, z. B. bei der Arbeit mit Instanzen
Spinner
– Sie stellen nur den Adapter bereit
selbst. Eine Bibliothek nimmt dann die Daten,
die in diesen Adapter geladen werden,
zeigt die Daten für Sie an. Ändern Sie in diesen Fällen den Typ des
die Daten des Adapters
LiveData<PagedList>
, dann Zeilenumbruch
diese Liste in einem ArrayAdapter
-Objekt
bevor Sie versuchen, die Elemente
auf einer Benutzeroberfläche von einer Bibliotheksklasse in die Luft zu treiben.
Inhalte mit AsyncListUtil asynchron laden
Wenn Sie
AsyncListUtil
-Objekte in
Gruppen von Informationen asynchron laden und anzeigen können, können Sie mit der Paging Library
einfacher laden:
- Ihre Daten müssen nicht positionell sein. Mit der Paging Library können Sie Daten mithilfe von Schlüsseln, die vom Netzwerk bereitgestellt werden, direkt aus Ihrem Back-End abzurufen.
- Ihre Daten können unendlich groß sein. Mit der Paging Library können Sie auf Seiten verteilt werden, bis keine Daten mehr vorhanden sind.
- Sie können Ihre Daten besser beobachten. Über die Paging-Bibliothek können Daten, die ViewModel Ihrer App in einer beobachtbaren Datenstruktur gespeichert wird.
Datenbankbeispiele
Die folgenden Code-Snippets zeigen mehrere Möglichkeiten, wie alle Teile zusammenarbeiten können.
Beobachten von Page-Daten mit LiveData
Das folgende Code-Snippet zeigt, wie alle Teile zusammenwirken. Als Konzert
Ereignisse in der Datenbank hinzugefügt, entfernt oder geändert werden, wird der Inhalt der Seite
RecyclerView
ist
automatisch und effizient aktualisiert:
Kotlin
@Dao interface ConcertDao { // The Int type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") fun concertsByDate(): DataSource.Factory<Int, Concert> } class ConcertViewModel(concertDao: ConcertDao) : ViewModel() { val concertList: LiveData<PagedList<Concert>> = concertDao.concertsByDate().toLiveData(pageSize = 50) } class ConcertActivity : AppCompatActivity() { public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Use the 'by viewModels()' Kotlin property delegate // from the activity-ktx artifact val viewModel: ConcertViewModel by viewModels() val recyclerView = findViewById(R.id.concert_list) val adapter = ConcertAdapter() viewModel.concertList.observe(this, PagedList(adapter::submitList)) recyclerView.setAdapter(adapter) } } class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null. holder.bindTo(concert) } companion object { private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // Concert details may have changed if reloaded from the database, // but ID is fixed. override fun areItemsTheSame(oldConcert: Concert, newConcert: Concert) = oldConcert.id == newConcert.id override fun areContentsTheSame(oldConcert: Concert, newConcert: Concert) = oldConcert == newConcert } } }
Java
@Dao public interface ConcertDao { // The Integer type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") DataSource.Factory<Integer, Concert> concertsByDate(); } public class ConcertViewModel extends ViewModel { private ConcertDao concertDao; public final LiveData<PagedList<Concert>> concertList; public ConcertViewModel(ConcertDao concertDao) { this.concertDao = concertDao; concertList = new LivePagedListBuilder<>( concertDao.concertsByDate(), /* page size */ 50).build(); } } public class ConcertActivity extends AppCompatActivity { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ConcertViewModel viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); RecyclerView recyclerView = findViewById(R.id.concert_list); ConcertAdapter adapter = new ConcertAdapter(); viewModel.concertList.observe(this, adapter::submitList); recyclerView.setAdapter(adapter); } } public class ConcertAdapter extends PagedListAdapter<Concert, ConcertViewHolder> { protected ConcertAdapter() { super(DIFF_CALLBACK); } @Override public void onBindViewHolder(@NonNull ConcertViewHolder holder, int position) { Concert concert = getItem(position); if (concert != null) { holder.bindTo(concert); } else { // Null defines a placeholder item - PagedListAdapter automatically // invalidates this row when the actual object is loaded from the // database. holder.clear(); } } private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = new DiffUtil.ItemCallback<Concert>() { // Concert details may have changed if reloaded from the database, // but ID is fixed. @Override public boolean areItemsTheSame(Concert oldConcert, Concert newConcert) { return oldConcert.getId() == newConcert.getId(); } @Override public boolean areContentsTheSame(Concert oldConcert, Concert newConcert) { return oldConcert.equals(newConcert); } }; }
Paged-Daten mit RxJava2 beobachten
Wenn Sie lieber
RxJava2 anstelle von
LiveData
können Sie stattdessen
Erstellen Sie ein Observable
- oder Flowable
-Objekt:
Kotlin
class ConcertViewModel(concertDao: ConcertDao) : ViewModel() { val concertList: Observable<PagedList<Concert>> = concertDao.concertsByDate().toObservable(pageSize = 50) }
Java
public class ConcertViewModel extends ViewModel { private ConcertDao concertDao; public final Observable<PagedList<Concert>> concertList; public ConcertViewModel(ConcertDao concertDao) { this.concertDao = concertDao; concertList = new RxPagedListBuilder<>( concertDao.concertsByDate(), /* page size */ 50) .buildObservable(); } }
Sie können die Beobachtung der Daten dann starten und beenden, indem Sie den folgenden Code verwenden: snippet:
Kotlin
class ConcertActivity : AppCompatActivity() { private val adapter = ConcertAdapter() // Use the 'by viewModels()' Kotlin property delegate // from the activity-ktx artifact private val viewModel: ConcertViewModel by viewModels() private val disposable = CompositeDisposable() public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val recyclerView = findViewById(R.id.concert_list) recyclerView.setAdapter(adapter) } override fun onStart() { super.onStart() disposable.add(viewModel.concertList .subscribe(adapter::submitList))) } override fun onStop() { super.onStop() disposable.clear() } }
Java
public class ConcertActivity extends AppCompatActivity { private ConcertAdapter adapter = new ConcertAdapter(); private ConcertViewModel viewModel; private CompositeDisposable disposable = new CompositeDisposable(); @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); RecyclerView recyclerView = findViewById(R.id.concert_list); viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); recyclerView.setAdapter(adapter); } @Override protected void onStart() { super.onStart(); disposable.add(viewModel.concertList .subscribe(adapter.submitList(flowableList) )); } @Override protected void onStop() { super.onStop(); disposable.clear(); } }
Der Code für ConcertDao
und ConcertAdapter
ist für einen
RxJava2-basiert
so wie für ein Unternehmen
LiveData
-basierte Lösung.
Feedback geben
Wir freuen uns über dein Feedback und deine Ideen:
- Problemverfolgung
- Melde Probleme, damit wir sie beheben können.
Weitere Informationen
Weitere Informationen zur Paging Library finden Sie in der in den folgenden Ressourcen.
Produktproben
- <ph type="x-smartling-placeholder"></ph> Paging für Komponenten der Android-Architektur Beispiel
- <ph type="x-smartling-placeholder"></ph> Beispiel für Paging mit Netzwerk
Codelabs
- <ph type="x-smartling-placeholder"></ph> Codelab zum Paging unter Android
Videos
- <ph type="x-smartling-placeholder"></ph> Android Jetpack: Unbegrenzte Listen mit RecyclerView und Paging verwalten (Google I/O 2018)
- <ph type="x-smartling-placeholder"></ph> Android Jetpack: Paging
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Zu Paging 3 migrieren
- Seitenlisten anzeigen
- Auslagerungsdaten erfassen