نقل البيانات إلى التنقل في الصفحات رقم 3

يختلف الإصدار 3 من مكتبة Paging اختلافًا كبيرًا عن الإصدارات السابقة من المكتبة. يوفّر هذا الإصدار وظائف محسّنة ويعالج المشاكل الشائعة التي تواجه المستخدمين عند استخدام الإصدار 2 من مكتبة Paging. إذا كان تطبيقك يستخدم إصدارًا قديمًا من مكتبة Paging، يمكنك الاطّلاع على هذه الصفحة لمعرفة المزيد حول الانتقال إلى الإصدار 3 من مكتبة Paging.

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

مزايا الانتقال إلى مكتبة Paging 3

يتضمّن الإصدار 3 من مكتبة Paging الميزات التالية التي لم تكن متوفّرة في الإصدارات السابقة من المكتبة:

  • توافق تام مع إجراءات Kotlin الفرعية وFlow
  • إتاحة التحميل غير المتزامن باستخدام عناصر RxJava Single أو Guava ListenableFuture الأساسية
  • إشارات مدمجة لحالة التحميل والأخطاء لتصميم واجهة مستخدم متجاوبة، بما في ذلك وظائف إعادة المحاولة وإعادة التحميل
  • تحسينات على طبقة المستودع، بما في ذلك إتاحة الإلغاء وواجهة مبسطة لمصدر البيانات
  • تحسينات على طبقة العرض وفواصل القوائم وعمليات تحويل الصفحات المخصّصة ورؤوس وتذييلات حالة التحميل

نقل تطبيقك إلى الإصدار 3 من مكتبة Paging

لإجراء عملية نقل البيانات بالكامل إلى مكتبة Paging 3، يجب نقل جميع المكوّنات الرئيسية الثلاثة من مكتبة Paging 2، وهي:

  • DataSource صفوف
  • PagedList
  • PagedListAdapter

ومع ذلك، تتوافق بعض مكوّنات Paging 3 مع الإصدارات السابقة من مكتبة Paging. على وجه الخصوص، يمكن أن تكون واجهة برمجة التطبيقات PagingSource من مكتبة Paging 3 مصدر بيانات للرمزين LivePagedListBuilder وRxPagedListBuilder من الإصدارات القديمة. وبالمثل، يمكن لواجهة برمجة التطبيقات Pager استخدام عناصر DataSource القديمة مع الطريقة asPagingSourceFactory(). وهذا يعني أنّ لديك خيارات النقل التالية:

  • يمكنك نقل DataSource إلى PagingSource بدون إجراء أي تغييرات على بقية عملية تنفيذ Paging.
  • يمكنك نقل بيانات PagedList وPagedListAdapter، ولكن سيظل بإمكانك استخدام واجهة برمجة التطبيقات القديمة DataSource.
  • يمكنك نقل عملية تنفيذ مكتبة Paging بأكملها لنقل تطبيقك بالكامل إلى الإصدار 3 من مكتبة Paging.

توضّح الأقسام في هذه الصفحة كيفية نقل مكوّنات Paging في كل طبقة من طبقات تطبيقك.

DataSource صفوف

يصف هذا القسم جميع التغييرات اللازمة لنقل عملية تنفيذ قديمة لخدمة Paging إلى استخدام PagingSource.

يتم دمج PageKeyedDataSource وPositionalDataSource وItemKeyedDataSource من مكتبة Paging 2 في واجهة برمجة التطبيقات PagingSource في مكتبة Paging 3. يتم دمج طرق التحميل من جميع فئات واجهة برمجة التطبيقات القديمة في طريقة load() واحدة في PagingSource. يؤدي ذلك إلى تقليل تكرار الرموز البرمجية لأنّ معظم المنطق في طرق التحميل ضمن عمليات تنفيذ فئات واجهة برمجة التطبيقات القديمة يكون متطابقًا في الغالب.

تم استبدال جميع مَعلمات طريقة التحميل في مكتبة Paging 3 LoadParamsبفئة محكمة الإغلاق، تتضمّن فئات فرعية لكل نوع تحميل. إذا كنت بحاجة إلى التمييز بين أنواع التحميل في طريقتك load()، تحقَّق من الفئة الفرعية LoadParams التي تم تمريرها: LoadParams.Refresh أو LoadParams.Prepend أو LoadParams.Append.

لمزيد من المعلومات حول تنفيذ PagingSource، يُرجى الاطّلاع على تحديد مصدر بيانات.

إعادة تحميل المفاتيح

يجب أن تحدّد عمليات تنفيذ PagingSource كيفية استئناف عمليات إعادة التحميل من منتصف بيانات الصفحة التي تم تحميلها. يمكنك إجراء ذلك من خلال تنفيذ getRefreshKey() لربط المفتاح الأولي الصحيح باستخدام state.anchorPosition كالفهرس الذي تم الوصول إليه مؤخرًا.

Kotlin

// Replaces ItemKeyedDataSource.
override fun getRefreshKey(state: PagingState<String, User>): String? {
  return state.anchorPosition?.let { anchorPosition ->
    state.getClosestItemToPosition(anchorPosition)?.id
  }
}

// Replacing PositionalDataSource.
override fun getRefreshKey(state: PagingState<Int, User>): Int? {
  return state.anchorPosition
}

Java

// Replaces ItemKeyedDataSource.
@Nullable
@Override
String getRefreshKey(state: PagingState<String, User>) {
  Integer anchorPosition = state.anchorPosition;
  if (anchorPosition == null) {
    return null;
  }

  return state.getClosestItemToPosition(anchorPosition);
}

// Replaces PositionalDataSource.
@Nullable
@Override
Integer getRefreshKey(state: PagingState<Integer, User>) {
  return state.anchorPosition;
}

Java

// Replacing ItemKeyedDataSource.
@Nullable
@Override
String getRefreshKey(state: PagingState<String, User>) {
  Integer anchorPosition = state.anchorPosition;
  if (anchorPosition == null) {
    return null;
  }

  return state.getClosestItemToPosition(anchorPosition);
}

// Replacing PositionalDataSource.
@Nullable
@Override
Integer getRefreshKey(state: PagingState<Integer, User>) {
  return state.anchorPosition;
}

عمليات تحويل القوائم

في الإصدارات الأقدم من مكتبة Paging، تعتمد عملية تحويل البيانات المقسّمة إلى صفحات على الطرق التالية:

  • DataSource.map()
  • DataSource.mapByPage()
  • DataSource.Factory.map()
  • DataSource.Factory.mapByPage()

في مكتبة Paging 3، يتم تطبيق جميع عمليات التحويل كعوامل على PagingData. إذا كنت تستخدم أيًا من الطرق الواردة في القائمة السابقة لتحويل قائمتك المقسّمة إلى صفحات، عليك نقل منطق التحويل من DataSource إلى PagingData عند إنشاء Pager باستخدام PagingSource الجديد.

لمزيد من المعلومات حول تطبيق عمليات التحويل على البيانات المقسّمة إلى صفحات باستخدام مكتبة Paging 3، يمكنك الاطّلاع على تحويل مصادر البيانات.

PagedList

يوضّح هذا القسم جميع التغييرات اللازمة لنقل عملية تنفيذ قديمة لمكتبة Paging إلى استخدام Pager وPagingData في الإصدار 3 من مكتبة Paging.

PagedListBuilder صفوف

يحلّ PagingData محلّ PagedList الحالي من "صفحة 2". للانتقال إلى PagingData، يجب تعديل ما يلي:

  • تم نقل إعدادات التقسيم إلى صفحات من PagedList.Config إلى PagingConfig.
  • تم دمج LivePagedListBuilder وRxPagedListBuilder في صف واحد هو Pager.
  • تعرض Pager عنصر Flow<PagingData> قابلاً للمراقبة باستخدام السمة .flow. تتوفّر أيضًا صيغ RxJava وLiveData كسمات إضافية يمكن استدعاؤها من Java باستخدام طرق ثابتة، ويتم توفيرها من الوحدتَين paging-rxjava* وpaging-runtime على التوالي.

Kotlin

val flow = Pager(
  // Configure how data is loaded by passing additional properties to
  // PagingConfig, such as prefetchDistance.
  PagingConfig(pageSize = 20)
) {
  ExamplePagingSource(backend, query)
}.flow
  .cachedIn(viewModelScope)

Java

// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact.
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel);
Pager<Integer, User> pager = Pager<>(
  new PagingConfig(/* pageSize = */ 20),
  () -> ExamplePagingSource(backend, query));

Flowable<PagingData<User>> flowable = PagingRx.getFlowable(pager);
PagingRx.cachedIn(flowable, viewModelScope);

Java

// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact.
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel);
Pager<Integer, User> pager = Pager<>(
  new PagingConfig(/* pageSize = */ 20),
  () -> ExamplePagingSource(backend, query));

PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope);

لمزيد من المعلومات حول إعداد مصدر تفاعلي لعناصر PagingData باستخدام مكتبة Paging 3، يمكنك الاطّلاع على إعداد مصدر PagingData.

BoundaryCallback للمستندات المصدر ذات الطبقات

في Paging 3، يحل RemoteMediator محل PagedList.BoundaryCallback كمعالج للتقسيم على صفحات من الشبكة وقاعدة البيانات.

لمزيد من المعلومات حول استخدام RemoteMediator للتنقل بين الصفحات من الشبكة وقاعدة البيانات في مكتبة Paging 3، يمكنك الاطّلاع على الدرس التطبيقي حول الترميز في Android Paging.

PagedListAdapter

يستخدم Paging 2 السمة PagedListAdapter لربط PagedList بـ RecyclerView. في مكتبة Paging 3، تم استبدال PagedList بـ PagingData. إذا كنت بصدد نقل تطبيقك لاستخدام Jetpack Compose في واجهة المستخدم، لن تحتاج إلى محوّل لعرض البيانات المقسّمة إلى صفحات.

بدلاً من ذلك، استخدِم العنصر paging-compose وطريقة الإضافة collectAsLazyPagingItems الخاصة به لجمع عناصر PagingData وعرضها في دوال @Composable مثل LazyColumn.

لمزيد من المعلومات حول استخدام مكتبة Paging 3 مع Jetpack Compose، يمكنك الاطّلاع على نظرة عامة على مكتبة Paging 3.

مراجع إضافية

لمزيد من المعلومات حول مكتبة Paging، يُرجى الاطّلاع على المراجع الإضافية التالية:

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

نماذج