Questa guida si basa sulla panoramica sulla libreria di pacchetti e descrive come presentare elenchi di informazioni agli utenti nella UI dell'app, in particolare quando queste informazioni cambiano.
Collega la tua UI al modello di visualizzazione
Puoi connettere un'istanza di
LiveData<PagedList>
a
PagedListAdapter
, come mostrato
nel seguente snippet di codice:
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() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); viewModel.concerts.observe(this, Observer { adapter.submitList(it) }) } }
Java
public class ConcertActivity extends AppCompatActivity { private ConcertAdapter adapter = new ConcertAdapter(); private ConcertViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); viewModel.concertList.observe(this, adapter::submitList); } }
Man mano che le origini dati forniscono nuove istanze di PagedList
, l'attività invia questi oggetti all'adattatore. L'implementazione di PagedListAdapter
definisce il modo in cui vengono calcolati gli aggiornamenti e gestisce automaticamente il impaginazione e la differenziazione degli elenchi. Pertanto, ViewHolder
deve essere associato solo a un determinato elemento fornito:
Kotlin
class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { override 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 = ... // See Implement the diffing callback section. } }
Java
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); // Note that "concert" can be null if it's a placeholder. holder.bindTo(concert); } private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = ... // See Implement the diffing callback section. }
L'elemento PagedListAdapter
gestisce gli eventi di caricamento pagina utilizzando un
oggetto
PagedList.Callback
. Mentre l'utente scorre, PagedListAdapter
chiama
PagedList.loadAround()
per fornire suggerimenti all'elemento
PagedList
sottostante su
quali elementi deve recuperare da
DataSource
.
Implementa il callback diverso
Il seguente esempio mostra un'implementazione manuale di
areContentsTheSame()
,
che confronta i campi oggetto pertinenti:
Kotlin
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id == newItem.id // If you use the "==" operator, make sure that the object implements // .equals(). Alternatively, write custom data comparison logic here. override fun areContentsTheSame( oldItem: Concert, newItem: Concert) = oldItem == newItem }
Java
private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = new DiffUtil.ItemCallback<Concert>() { @Override public boolean areItemsTheSame(Concert oldItem, Concert newItem) { // The ID property identifies when items are the same. return oldItem.getId() == newItem.getId(); } @Override public boolean areContentsTheSame(Concert oldItem, Concert newItem) { // Don't use the "==" operator here. Either implement and use .equals(), // or write custom data comparison logic here. return oldItem.equals(newItem); } };
Poiché l'adattatore include la tua definizione di confronto degli elementi, rileva automaticamente le modifiche a questi elementi quando viene caricato un nuovo oggetto PagedList
. Di conseguenza, l'adattatore attiva animazioni efficaci degli elementi all'interno dell'oggetto RecyclerView
.
Differenza con l'utilizzo di un tipo di adattatore diverso
Se scegli di non ereditare da PagedListAdapter
, ad esempio quando utilizzi una libreria che fornisce il proprio adattatore, puoi comunque utilizzare la funzionalità di differenziazione dell'adattatore della Raccolta di pagine lavorando direttamente con un oggetto AsyncPagedListDiffer
.
Fornire segnaposto nell'interfaccia utente
Se vuoi che la UI mostri un elenco prima che l'app abbia terminato il recupero dei dati, puoi mostrare agli utenti le voci dell'elenco segnaposto. L'elemento
PagedList
gestisce questo caso presentando i dati degli elementi dell'elenco come null
fino al caricamento dei dati.
I segnaposto offrono i seguenti vantaggi:
- Supporto per barre di scorrimento:
PagedList
fornisce il numero di elementi dell'elenco aPagedListAdapter
. Queste informazioni consentono all'adattatore di tracciare una barra di scorrimento che mostra la dimensione intera dell'elenco. Quando vengono caricate nuove pagine, la barra di scorrimento non salta perché la dimensione dell'elenco non cambia. - Nessuna icona di caricamento necessaria: poiché la dimensione dell'elenco è già nota, non è necessario avvisare gli utenti che è in corso il caricamento di altri elementi. I segnaposto stessi trasmettono queste informazioni.
Tuttavia, prima di aggiungere il supporto per i segnaposto, tieni presente le seguenti condizioni preliminari:
- Richiede un set di dati conteggiabile: le istanze di
DataSource
della libreria di persistenza delle stanze possono conteggiare gli elementi in modo efficiente. Tuttavia, se utilizzi una soluzione di archiviazione locale personalizzata o un'architettura dei dati di sola rete, potrebbe essere costoso, o addirittura impossibile, determinare quanti elementi compongono il set di dati. - Richiede l'adattatore per tenere conto degli elementi non caricati: l'adattatore o il meccanismo di presentazione che utilizzi per preparare l'elenco per l'inflazione deve gestire elementi dell'elenco nulli. Ad esempio, quando associ i dati a una
ViewHolder
, devi fornire valori predefiniti per rappresentare i dati non caricati. - Richiede visualizzazioni degli elementi della stessa dimensione: se le dimensioni degli elementi dell'elenco possono cambiare in base ai relativi contenuti, ad esempio gli aggiornamenti dei social network, la dissolvenza incrociata tra gli elementi non sembra corretta. In questo caso consigliamo vivamente di disabilitare i segnaposto.
Fornisci feedback
Condividi il tuo feedback e le tue idee con noi attraverso queste risorse:
- Issue Tracker
- Segnala i problemi per consentirci di correggerli.
Risorse aggiuntive
Per scoprire di più sulla libreria di paging, consulta le risorse seguenti.
Samples
Codelab
Video
- Android Jetpack: gestire elenchi infiniti con RecyclerView e Paging (Google I/O '18)
- Android Jetpack: paging
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Panoramica della raccolta Paging 2
- Eseguire la migrazione a Paging 3
- Raccogliere dati su pagine