Dans ce tutoriel, je vais vous montrer comment utiliser la bibliothèque de pagination à partir des composants d'architecture Android avec une base de données assortie d'une pièce dans une application Android..
Vous apprendrez à utiliser la bibliothèque de radiomessagerie pour charger efficacement des ensembles de données volumineux à partir d'une base de données assortie d'une pièce, offrant ainsi à vos utilisateurs une expérience plus fluide tout en faisant défiler une fenêtre RecyclerView.
Pour pouvoir suivre ce tutoriel, vous aurez besoin de:
Données en direct
et base de données des chambres)Si vous ne connaissez pas les composants de l'architecture, nous vous conseillons vivement de consulter notre impressionnante série consacrée aux composants d'architecture Android de Tin Megali. Assurez-vous d'aller plonger!
Vous trouverez un exemple de projet pour ce tutoriel sur notre dépôt GitHub afin que vous puissiez suivre facilement.
La bibliothèque de pagination est une autre bibliothèque ajoutée aux composants d'architecture. La bibliothèque permet de gérer efficacement le chargement et l’affichage d’un grand ensemble de données dans RecyclerVoir
. Selon les documents officiels:
La bibliothèque de radiomessagerie simplifie le chargement des données progressivement et avec élégance dans votre application.RecyclerVoir
.
Si une partie de votre application Android doit afficher un grand ensemble de données à partir d'une source de données locale ou distante, mais n'en afficher qu'une partie à la fois, vous devez envisager d'utiliser la bibliothèque de pagination. Cela aidera à améliorer les performances de votre application.!
Maintenant que vous avez vu une introduction à la bibliothèque de pagination, vous pouvez vous demander pourquoi l’utiliser. Voici quelques raisons pour lesquelles vous devriez envisager de l’utiliser lors du chargement de grands ensembles de données dans un environnement donné. RecyclerVoir
.
Cela ne sera pas efficace lorsque vous travaillerez avec une grande quantité de données, car la source de données sous-jacente récupérera toutes les données, même si seul un sous-ensemble de ces données sera affiché à l'utilisateur. Dans une telle situation, nous devrions envisager de paginer les données.
Lancez votre Android Studio 3 et créez un nouveau projet avec une activité vide appelée Activité principale
. Assurez-vous de vérifier Inclure le support Kotlin.
Après avoir créé un nouveau projet, ajoutez les dépendances suivantes dans votre build.gradle. Dans ce tutoriel, nous utilisons la dernière version de la bibliothèque Paging 1.0.1, alors que Room est la version 1.1.1 (à ce jour).
dépendances implementation fileTree (dir: 'libs', include: ['* .jar'])) implémentation "android.arch.persistence.room:runtime:1.1.1" kapt "android.arch.persistence.room:compiler:1.1 .1 "implementation" android.arch.paging: runtime: 1.0.1 "implémentation" com.android.support:recyclerview-v7:27.1.1 "
Ces artefacts sont disponibles sur le référentiel Maven de Google..
allprojects repositories google () jcenter ()
En ajoutant les dépendances, nous avons appris à Gradle comment trouver la bibliothèque. N'oubliez pas de synchroniser votre projet après les avoir ajoutés.
Créer une nouvelle classe de données Kotlin La personne
. Par souci de simplicité, notre La personne
L'entité n'a que deux champs:
identifiant
)prénom
)En outre, inclure un toString (
méthode qui retourne simplement le prénom
.
import android.arch.persistence.room.Entity import android.arch.persistence.room.PrimaryKey @Entity (tableName = "personnes") Classe de données person (@PrimaryKey id id: String, nom id: String) remplace fun toString ( ) = nom
Comme vous le savez, pour que nous puissions accéder aux données de notre application avec la bibliothèque Room, nous avons besoin d'objets DAO. Dans notre propre cas, nous avons créé un PersonDao
.
importer android.arch.lifecycle.LiveData importer android.arch.paging.DataSource importer android.arch.persistence.room.Dao importer android.arch.persistence.room.Delete importer android.arch.persistence.room.Insert importer android.arch .persistence.room.Query @Dao interface PersonDao @Query ("SELECT * FROM personnes") fun getAll (): LiveData> @Query ("SELECT * FROM personnes") fun getAllPaged (): DataSource.Factory
@Insert fun insertAll (personnes: liste ) @Delete fun delete (personne: Personne)
Dans notre PersonDao
classe, nous avons deux @Question
méthodes. L'un d'eux est Avoir tout()
, qui retourne un Données en direct
qui détient une liste de La personne
objets. L'autre est getAllPaged ()
, qui retourne un DataSource.Factory
.
Selon les documents officiels, le La source de données
la classe est la:
Classe de base pour le chargement de pages de données d'instantané dans un PagedList
.
UNE PagedList
est un genre particulier de liste
pour afficher des données paginées dans Android:
UNEPagedList
est une liste qui charge ses données en morceaux (pages) depuis unLa source de données
. Les articles peuvent être consultés avecget (int)
, et le chargement ultérieur peut être déclenché avecloadAround (int)
.
Nous avons appelé le Usine
méthode statique dans le La source de données
class, qui sert de fabrique (créer des objets sans avoir à spécifier la classe exacte de l’objet qui sera créé) pour le La source de données
. Cette méthode statique prend en deux types de données:
La source de données
. Notez que pour une requête de salle, les pages sont numérotées. Nous utilisons donc Entier
comme type d'identifiant de page. Il est possible d'avoir des pages "à clé" en utilisant la bibliothèque de pagination, mais Room ne propose pas cela. La source de données
s.Voici ce que notre classe de base de données Room AppDatabase
ressemble à:
importer android.arch.persistence.db.SupportSQLiteDatabase importer android.arch.persistence.room.Database importer android.arch.persistence.room.Room importer android.arch.persistence.room.RoomDatabase importer android.content.Context import androidx.work .OneTimeWorkRequestBuilder import androidx.work.WorkManager import com.chikeandroid.pagingtutsplus.utils.DATABASE_NAME import com.chikeandroid.pagingtutsplus.workers.SeedDatabaseWorker @Database (entités = [Personne :: Classe, personne], version = 1, exportSema AppDatabase: RoomDatabase () abstract fun personDao (): Objet compagnon PersonDao // Pour l'instanciation Singleton @Volatile private var instance: AppDatabase? = null fun getInstance (contexte: contexte): AppDatabase instance de retour?: synchronized (this) instance?: buildDatabase (contexte) .also instance = it amusement privé buildDatabase (contexte: Contexte): AppDatabase salle de retour .databaseBuilder (contexte, AppDatabase :: class.java, DATABASE_NAME) .addCallback (object: RoomDatabase.Callback () substitue l'amusement onCreate (db: SupportSQLiteDatabase) super.onCreate (db) val request = OneTimeWorkRequestBuilder() .build () WorkManager.getInstance ()?. enqueue (request)) .build ()
Ici, nous avons créé une instance unique de notre base de données et pré-remplie avec des données à l'aide de la nouvelle API WorkManager. Notez que les données pré-remplies sont juste une liste de 1 000 noms (plonger dans l'exemple de code source fourni pour en savoir plus)..
Pour que notre interface utilisateur stocke, observe et serve les données de manière consciente du cycle de vie, nous avons besoin d’un ViewModel
. Notre PersonnesVueModèle
, qui étend la AndroidViewModel
classe, va fonctionner comme notre ViewModel
.
import android.app.Application import android.arch.lifecycle.AndroidViewModel import android.arch.lifecycle.LiveData import android.arch.paging.DataSource import android.arch.paging.LivePagedListBuilder import android.arch.paging.Paging.PagedList import com.chikeandroid .pagingtutsplus.data.AppDatabase importer com.chikeandroid.pagingtutsplus.data.Person, classe PersonsViewModel, constructeur (application: Application): AndroidViewModel (application) private var personsLiveData: LiveData> init val factory: DataSource.Factory = AppDatabase.getInstance (getApplication ()). PersonDao (). GetAllPaged () val pagedListBuilder: LivePagedListBuilder = LivePagedListBuilder (usine, 50) personnesLiveData = pagedListBuilder.build () fun getPersonsLiveData () = personnesLiveData
Dans cette classe, nous avons un seul champ appelé personnesDonnéesDonnées
. Ce champ est simplement un Données en direct
qui détient un PagedList
de La personne
objets. Parce que c'est un Données en direct
, notre interface utilisateur (la Activité
ou Fragment
) va observer ces données en appelant la méthode getter getPersonsLiveData ()
.
Nous avons initialisé personnesDonnéesDonnées
à l'intérieur de init
bloc. À l'intérieur de ce bloc, nous obtenons le DataSource.Factory
en appelant le AppDatabase
singleton pour le PersonDao
objet. Lorsque nous obtenons cet objet, nous appelons getAllPaged ()
.
Nous créons ensuite un LivePagedListBuilder
. Voici ce que dit la documentation officielle sur un LivePagedListBuilder
:
Constructeur pourDonnées en direct
, Donné unDataSource.Factory
et unPagedList.Config
.
Nous fournissons à son constructeur un DataSource.Factory
comme premier argument et la taille de la page comme second argument (dans notre cas, la taille de la page sera 50). En règle générale, vous devez choisir une taille supérieure au nombre maximal que vous pouvez afficher en une fois pour l'utilisateur. En fin de compte, nous appelons construire()
pour construire et nous rendre un Données en direct
.
Pour montrer notre PagedList
données dans un RecyclerVoir
, nous avons besoin d'un PagedListAdapter
. Voici une définition claire de cette classe de la documentation officielle:
RecyclerView.Adapter
classe de base pour la présentation de données paginées à partir dePagedList
s dans unRecyclerVoir
.
Alors on crée un PersonAdapter
qui s'étend PagedListAdapter
.
import android.arch.paging.PagedListAdapter import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import com .chikeandroid.pagingtutsplus.R importer com.chikeandroid.pagingtutsplus.data.Person importer kotlinx.android.synthetic.main.item_person.view. * class PersonAdapter (contexte de val: Contexte): PagedListAdapter(PersonDiffCallback ()) substitue l'amusement onBindViewHolder (holderPerson: PersonViewHolder, position: Int) var person = getItem (position) if (personne == null) holderPerson.clear () autre holderPerson.bind (personne) Remplacez l'amusement onCreateViewHolder (parent: ViewGroup, viewType: Int): PersonViewHolder return PersonViewHolder (LayoutInflater.from (context). .inflate (R.layout.item_person, parent, false)) class PersonViewHolder (vue: vue): RecyclerView.ViewHolder (vue) var tvName: TextView = view.name fun bind (personne: Personne) tvName.text = personne.name fun clear () tvName.text = null
PagedListAdapter
est utilisé comme toute autre sous-classe de RecyclerView.Adapter
. En d'autres termes, vous devez implémenter les méthodes onCreateViewHolder ()
et onBindViewHolder ()
.
Pour étendre le PagedListAdapter
classe abstraite, vous devrez fournir dans son constructeur le type de PageLists
(cela devrait être une ancienne classe Java simple: un POJO) et aussi une classe qui étend le ViewHolder
qui sera utilisé par l'adaptateur. Dans notre cas, nous lui avons donné La personne
et PersonViewHolder
comme premier et deuxième argument respectivement.
Notez que PagedListAdapter
exige que vous passiez un DiffUtil.ItemCallback
au PageListAdapter
constructeur. DiffUtil
est un RecyclerVoir
classe utilitaire capable de calculer la différence entre deux listes et de générer une liste d'opérations de mise à jour qui convertit la première liste en une seconde. ItemCallback
est une classe statique abstraite intérieure (à l'intérieur DiffUtil
) utilisé pour calculer le diff entre deux éléments non nuls d'une liste.
Plus précisément, nous fournissons PersonDiffCallback
à notre PagedListAdapter
constructeur.
import android.support.v7.util.DiffUtil import com.chikeandroid.pagingtutsplus.data.Person classe PersonDiffCallback: DiffUtil.ItemCallback() redéfinit fun areItemsTheSame (oldItem: Person, newItem: Personne): Boolean return oldItem.id == newItem.id annule fun areContentsTheSame (oldItem: Personne ?, newItem: Personne?): Boolean retour oldItem == newItem
Parce que nous mettons en œuvre DiffUtil.ItemCallback
, nous devons mettre en œuvre deux méthodes: areItemsTheSame ()
et areContentsTheSame ()
.
areItemsTheSame
est appelé pour vérifier si deux objets représentent le même élément. Par exemple, si vos éléments ont des identifiants uniques, cette méthode doit vérifier leur égalité d'identifiant. Cette méthode retourne vrai
si les deux éléments représentent le même objet ou faux
si elles sont différentes.areContentsTheSame
est appelé pour vérifier si deux éléments ont les mêmes données. Cette méthode retourne vrai
si le contenu des articles est identique ou faux
si elles sont différentes.Notre PersonViewHolder
classe intérieure est juste un typique RecyclerView.ViewHolder
. Il est responsable de la liaison des données nécessaires de notre modèle dans les widgets pour une ligne de notre liste..
classe PersonAdapter (val contexte: contexte): PagedListAdapter(PersonDiffCallback ()) //… class PersonViewHolder (vue: vue): RecyclerView.ViewHolder (vue) var nomVue: TextView = vue.nom fun lier (personne: Personne) nomNom.text = personne.nom amusement clear () tvName.text = null
Dans notre onCreate ()
de nôtre Activité principale
, nous avons simplement fait ce qui suit:
voirModèle
champ utilisant la classe d'utilitaire ViewModelProviders
PersonAdapter
RecyclerVoir
PersonAdapter
au RecyclerVoir
Données en direct
et soumettre le PagedList
objets sur le PersonAdapter
en invoquant submitList ()
importer android.arch.lifecycle.Observer importer android.arch.lifecycle.ViewModelProviders importer android.os.Bundle importer android.support.v7.app.AppCompatActivity importer android.support.v7.widget.Recycler.import.r. .PersonAdapter import com.chikeandroid.pagingtutsplus.viewmodels.PersonsViewModel classe MainActivity: AppCompatActivity () private tardive viewPodel: SubjectViewModel fun onCreate (savedInstanceState: Bundle?) = ViewModelProviders.of (this) .get (PersonsViewModel :: class.java) val adaptateur = PersonAdapter (this) findViewById(R.id.name_list) .adapter = adaptateur subscribeUi (adaptateur) amusement privé subscribeUi (adaptateur: PersonAdapter) viewModel.getPersonLiveData (). Observe (this, Observateur noms -> if (noms! = Null) adapter.submitList (des noms) )
Enfin, lorsque vous exécutez l'application, voici le résultat:
Lors du défilement, Room est en mesure de prévenir les lacunes en chargeant 50 éléments à la fois et en les mettant à la disposition de notre PersonAdapter
, qui est une sous-classe de PagingListAdapter
. Mais notez que toutes les sources de données ne seront pas chargées rapidement. La vitesse de chargement dépend également de la puissance de traitement de l'appareil Android..
Si vous utilisez ou souhaitez utiliser RxJava dans votre projet, la bibliothèque de pagination inclut un autre artefact utile: RxPagedListBuilder
. Vous utilisez cet artefact au lieu de LivePagedListBuilder
pour le support RxJava.
Vous créez simplement une instance de RxPagedListBuilder
, fournir les mêmes arguments que vous le feriez pour LivePagedListBuilder
-la DataSource.Factory
et la taille de la page. Vous appelez alors buildObservable ()
ou buildFlowable ()
renvoyer un Observable
ou Fluide
pour votre PagedList
respectivement.
Fournir explicitement le Planificateur
pour le travail de chargement de données, vous appelez la méthode setter setFetchScheduler ()
. Fournir également le Planificateur
pour fournir le résultat (par exemple. AndroidSchedulers.mainThread ()
), appelez simplement setNotifyScheduler ()
. Par défaut, setNotifyScheduler ()
par défaut, le fil de l'interface utilisateur, setFetchScheduler ()
par défaut, le pool de threads d'E / S.
Dans ce didacticiel, vous avez appris à utiliser facilement le composant de pagination à partir des composants d'architecture Android (qui font partie d'Android Jetpack) avec Room. Cela nous aide à charger efficacement de grands ensembles de données à partir de la base de données locale pour permettre une expérience utilisateur plus fluide tout en faisant défiler une liste dans la liste. RecyclerVoir
.
Je recommande fortement de consulter la documentation officielle pour en savoir plus sur la bibliothèque de pagination dans Android.