Listen mit Seitennummern anzeigen

Dieses Dokument baut auf der Übersicht über die Paging-Bibliothek auf und beschreibt, wie Sie Nutzern in der Benutzeroberfläche Ihrer App Listen mit Informationen präsentieren können, insbesondere wenn sich diese Informationen ändern.

UI mit dem Ansichtsmodell verbinden

Sie können eine Instanz von LiveData<PagedList> mit einem PagedListAdapter verbinden, wie im folgenden Code-Snippet gezeigt:

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);
    }
}

Wenn Datenquellen neue Instanzen von PagedList bereitstellen, sendet die Aktivität diese Objekte an den Adapter. Die PagedListAdapter-Implementierung definiert, wie Aktualisierungen berechnet werden, und übernimmt automatisch das Paging und die Listendifferenzierung. Daher muss Ihr ViewHolder nur an ein bestimmtes bereitgestelltes Element gebunden werden:

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.
}

Der PagedListAdapter verarbeitet Seitenaufbau-Ereignisse mit einem PagedList.Callback-Objekt. Während der Nutzer scrollt, ruft der PagedListAdapter PagedList.loadAround() auf, um dem zugrunde liegenden PagedList Hinweise darauf zu geben, welche Elemente aus dem DataSource abgerufen werden sollen.

Diffing-Callback implementieren

Das folgende Beispiel zeigt eine manuelle Implementierung von areContentsTheSame(), bei der relevante Objektfelder verglichen werden:

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);
    }
};

Da der Adapter Ihre Definition zum Vergleichen von Elementen enthält, erkennt er automatisch Änderungen an diesen Elementen, wenn ein neues PagedList-Objekt geladen wird. Dadurch löst der Adapter effiziente Elementanimationen in Ihrem RecyclerView-Objekt aus.

Diffing mit einem anderen Adaptertyp

Wenn Sie nicht von PagedListAdapter übernehmen möchten, z. B. wenn Sie eine Bibliothek mit einem eigenen Adapter verwenden, können Sie die Diffing-Funktion des Paging Library-Adapters trotzdem verwenden, indem Sie direkt mit einem AsyncPagedListDiffer-Objekt arbeiten.

Platzhalter in der Benutzeroberfläche bereitstellen

Wenn du möchtest, dass deine Benutzeroberfläche eine Liste anzeigt, bevor deine App die Daten vollständig abgerufen hat, kannst du den Nutzern Platzhalter-Listenelemente anzeigen. In der PagedList wird dieser Fall so gehandhabt, dass die Artikeldaten als null dargestellt werden, bis die Daten geladen sind.

Platzhalter haben folgende Vorteile:

  • Unterstützung für Scrollleisten: Der PagedList stellt dem PagedListAdapter die Anzahl der Listenelemente zur Verfügung. Anhand dieser Informationen kann der Adapter eine Bildlaufleiste zeichnen, die die volle Größe der Liste wiedergibt. Wenn neue Seiten geladen werden, springt die Bildlaufleiste nicht, da sich die Größe der Liste nicht ändert.
  • Kein Ladesymbol erforderlich: Da die Listengröße bereits bekannt ist, müssen Nutzer nicht darüber informiert werden, dass weitere Elemente geladen werden. Die Platzhalter selbst vermitteln diese Informationen.

Bevor Sie die Unterstützung für Platzhalter hinzufügen, sollten Sie die folgenden Voraussetzungen beachten:

  • Erfordert ein zählbares Dataset: Instanzen von DataSource aus der Room-Persistenzbibliothek können ihre Elemente effizient zählen. Wenn Sie jedoch eine benutzerdefinierte lokale Speicherlösung oder eine reine Netzwerkdatenarchitektur verwenden, kann es teuer oder sogar unmöglich sein, die Anzahl der Elemente in Ihrem Dataset zu bestimmen.
  • Adapter erforderlich, um nicht geladene Elemente zu berücksichtigen: Der Adapter oder Präsentationsmechanismus, den du verwendest, um die Liste für die Inflation vorzubereiten, muss Null-Listenelemente verarbeiten können. Wenn Sie beispielsweise Daten an ein ViewHolder binden, müssen Sie Standardwerte angeben, um nicht geladene Daten darzustellen.
  • Erfordert gleich große Elementansichten: Wenn sich die Größe von Listenelementen je nach Inhalt ändern kann, z. B. bei Updates in sozialen Netzwerken, sieht das Überblenden zwischen Elementen nicht gut aus. In diesem Fall empfehlen wir dringend, Platzhalter zu deaktivieren.

Feedback geben

Über die folgenden Ressourcen können Sie uns Feedback geben und Ideen mitteilen:

Issue Tracker
Melden Sie Probleme, damit wir Fehler beheben können.

Zusätzliche Ressourcen

Weitere Informationen zur Paging-Bibliothek findest du in den folgenden Ressourcen.

Beispiele

Codelabs

Videos