عرض القوائم المقسّمة على صفحات

يعتمد هذا الدليل على نظرة عامة على "مكتبة الصفحات"، وتصف كيفية تقديم قوائم معلومات للمستخدمين في واجهة المستخدم الخاصة بتطبيقك، لا سيما عند تغيير هذه المعلومات.

ربط واجهة المستخدم بنموذج العرض

يمكنك ربط مثيل LiveData<PagedList> بـ PagedListAdapter، كما هو موضّح في مقتطف الرمز التالي:

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

ونظرًا لأن مصادر البيانات توفّر نُسخًا جديدة من PagedList، يرسل النشاط هذه العناصر إلى المحوِّل. ويحدِّد تنفيذ PagedListAdapter كيفية احتساب التحديثات، كما أنه يعالج تلقائيًا الاختلافات في الصفحات والقوائم. وبالتالي، يحتاج ViewHolder إلى الربط بعنصر محدّد فقط:

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 أحداث تحميل الصفحات باستخدام كائن PagedList.Callback. أثناء تنقّل المستخدم في الصفحة، يطلب PagedListAdapter PagedList.loadAround() لتقديم تلميحات إلى PagedList الأساسية بشأن العناصر التي يجب أن يجلبها من DataSource.

تنفيذ معاودة الاتصال المتباينة

يوضِّح النموذج التالي التنفيذ اليدوي للسمة areContentsTheSame()، التي تقارن بين حقول العناصر ذات الصلة:

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

بما أنّ المحوِّل يتضمّن تعريفك لمقارنة العناصر، يرصد المحوِّل تلقائيًا التغييرات التي تطرأ على هذه العناصر عند تحميل عنصر PagedList جديد. ونتيجةً لذلك، يشغِّل المحوِّل صورًا متحركة فعّالة للعناصر داخل عنصر RecyclerView.

الفارق باستخدام نوع محوِّل مختلف

إذا اخترت عدم الموروث من PagedListAdapter، مثلاً عند استخدام مكتبة توفّر محوِّلًا خاصًا بها، سيظل بإمكانك استخدام وظيفة الاختلاف في محوِّل "مكتبة الصفحات" من خلال العمل مباشرةً باستخدام كائن AsyncPagedListDiffer.

توفير العناصر النائبة في واجهة المستخدم

في الحالات التي تريد فيها أن تعرض واجهة المستخدم قائمة قبل أن ينتهي تطبيقك من جلب البيانات، يمكنك عرض عناصر قائمة العناصر النائبة للمستخدمين. تعالج PagedList هذه الحالة من خلال عرض بيانات عناصر القائمة على أنّها null إلى أن يتم تحميل البيانات.

وتتمتع العناصر النائبة بالمزايا التالية:

  • إتاحة أشرطة التمرير: توفّر السمة PagedList عدد عناصر القائمة PagedListAdapter. تسمح هذه المعلومات للمحوّل برسم شريط تمرير ينقل الحجم الكامل للقائمة. فأثناء تحميل صفحات جديدة، لا يقفز شريط التمرير بسبب عدم تغيير حجم القائمة.
  • دليل دوار التحميل غير ضروري: بما أنّ حجم القائمة معروف مسبقًا، لا حاجة لتنبيه المستخدمين بأنّه يتم تحميل المزيد من العناصر. العناصر النائبة نفسها تنقل تلك المعلومات.

قبل إضافة دعم للعناصر النائبة، ضع في اعتبارك الشروط المسبقة التالية:

  • تتطلب مجموعة بيانات قابلة للإحصاء: يمكن لمثيلات DataSource من مكتبة استمرار الغرفة عد العناصر بفعالية. إذا كنت تستخدم حل تخزين محلي مخصصًا أو بنية بيانات للشبكة فقط، فقد يكون من المكلف أو حتى من المستحيل تحديد عدد العناصر التي تشكل مجموعة البيانات.
  • يتطلب المحوّل مراعاة العناصر التي لم يتم تحميلها: المحوِّل أو آلية العرض التقديمي التي تستخدمها لإعداد قائمة التضخّم يجب أن تعالج عناصر القائمة الفارغة. على سبيل المثال، عند ربط البيانات بـ ViewHolder، عليك توفير قيم تلقائية لتمثيل البيانات التي تم إلغاء تحميلها.
  • تتطلب طرق عرض العناصر بنفس الحجم: إذا كان من الممكن أن تتغير أحجام عناصر القائمة بناءً على المحتوى، مثل تحديثات الشبكات الاجتماعية، فإن التلاشي بين العناصر لا يبدو جيدًا. نقترح بشدة تعطيل العناصر النائبة في هذه الحالة.

تقديم ملاحظات

يُرجى مشاركة ملاحظاتك وآرائك معنا من خلال الموارد التالية:

أداة تتبّع المشاكل
يمكنك الإبلاغ عن المشاكل حتى نتمكّن من إصلاح الأخطاء.

مراجع إضافية

لمعرفة المزيد حول مكتبة الترحيل، يمكنك الرجوع إلى الموارد التالية.

عيّنات

الدروس التطبيقية حول الترميز

الفيديوهات الطويلة