Tampilkan daftar yang disimpan

Dokumen ini dibuat berdasarkan ringkasan Library Paging, yang menjelaskan cara menyajikan daftar informasi kepada pengguna di UI aplikasi, terutama saat informasi ini berubah.

Menghubungkan UI ke model tampilan

Anda dapat menghubungkan instance LiveData<PagedList> ke PagedListAdapter, seperti yang ditunjukkan dalam cuplikan kode berikut:

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

Saat sumber data menyediakan instance baru PagedList, aktivitas akan mengirimkan objek ini ke adaptor. Implementasi PagedListAdapter menentukan cara penghitungan update, serta menangani paging dan perbedaan daftar secara otomatis. Oleh karena itu, ViewHolder Anda hanya perlu mengikat ke item tertentu yang disediakan:

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

PagedListAdapter menangani peristiwa pemuatan halaman menggunakan objek PagedList.Callback. Saat pengguna men-scroll, PagedListAdapter memanggil PagedList.loadAround() untuk memberikan petunjuk ke PagedList yang mendasarinya terkait item yang harus diambil dari DataSource.

Menerapkan callback diffing

Contoh berikut menunjukkan implementasi manual areContentsTheSame(), yang membandingkan kolom objek yang relevan:

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

Karena adaptor Anda menyertakan definisi untuk membandingkan item, adaptor akan otomatis mendeteksi perubahan pada item ini saat objek PagedList baru dimuat. Akibatnya, adaptor memicu animasi item yang efisien dalam objek RecyclerView Anda.

Menjalankan diffing menggunakan jenis adaptor berbeda

Jika Anda memilih untuk tidak mewarisi dari PagedListAdapter—seperti saat Anda menggunakan library yang menyediakan adapternya sendiri—Anda masih dapat menggunakan fungsi pembedaan adaptor Library Paging dengan bekerja langsung dengan objek AsyncPagedListDiffer.

Menyediakan placeholder di UI Anda

Jika ingin UI Anda menampilkan daftar sebelum aplikasi selesai mengambil data, Anda dapat menampilkan item daftar placeholder kepada pengguna. PagedList menangani kasus ini dengan menampilkan data item daftar sebagai null hingga data dimuat.

Placeholder memiliki manfaat sebagai berikut:

  • Dukungan untuk scrollbar: PagedList memberikan jumlah item daftar ke PagedListAdapter. Informasi ini memungkinkan adaptor menggambar scrollbar yang menampilkan ukuran penuh daftar. Saat halaman baru dimuat, scrollbar tidak akan melompat karena ukuran daftar Anda tidak berubah.
  • Tidak perlu menampilkan indikator lingkaran berputar pemuatan: Karena ukuran daftar sudah diketahui, tidak perlu memberi tahu pengguna bahwa ada item lain yang dimuat. Placeholder itu sendiri sudah menyampaikan informasi tersebut.

Sebelum menambahkan dukungan untuk placeholder, perhatikan prasyarat berikut:

  • Memerlukan set data yang dapat dihitung: Instance DataSource dari library persistensi Room dapat menghitung itemnya secara efisien. Namun, jika Anda menggunakan solusi penyimpanan lokal kustom atau arsitektur data khusus jaringan, mungkin akan mahal atau bahkan tidak mungkin untuk menentukan jumlah item yang membentuk set data Anda.
  • Memerlukan adaptor untuk memperhitungkan item yang tidak dimuat: Adaptor atau mekanisme presentasi yang Anda gunakan untuk menyiapkan daftar untuk di-inflate harus menangani item daftar null. Misalnya, saat mengikat data ke ViewHolder, Anda perlu memberikan nilai default untuk mewakili data yang tidak dimuat.
  • Memerlukan tampilan item berukuran sama: Jika ukuran item daftar dapat berubah berdasarkan kontennya, seperti update jejaring sosial, crossfade antar-item tidak akan terlihat bagus. Dalam hal ini, sebaiknya nonaktifkan placeholder.

Berikan masukan

Sampaikan masukan dan ide Anda kepada kami melalui resource berikut:

Issue tracker
Laporkan masalah agar kami dapat memperbaiki bug.

Referensi lainnya

Untuk mempelajari Library Paging lebih lanjut, lihat referensi berikut.

Contoh

Codelab

Video