Paging 3 значительно отличается от предыдущих версий библиотеки Paging. Эта версия предлагает расширенную функциональность, первоклассную поддержку сопрограмм Kotlin и Flow , а также бесшовную интеграцию с Jetpack Compose.
Преимущества перехода на пейджинг 3
В Paging 3 добавлены следующие функции, отсутствовавшие в более ранних версиях библиотеки:
- Первоклассная поддержка сопрограмм Kotlin и
Flow. - Встроенные сигналы состояния загрузки и ошибок для адаптивного дизайна пользовательского интерфейса, включая функции повторной попытки и обновления.
- Улучшения в уровне репозитория, включая поддержку отмены и упрощенный интерфейс источника данных.
- Улучшения в уровне представления, разделителях списков, пользовательских преобразованиях страниц, верхних и нижних колонтитулах, а также элементах состояния загрузки для ленивых списков.
Переведите ваше приложение на Paging 3.
Для полного перехода на систему пейджинга 3 необходимо перенести следующие основные компоненты из системы пейджинга 2:
- Классы
DataSource -
PagedList - Слой представления (для
LazyPagingItems)
Однако некоторые компоненты Paging 3 обратно совместимы с предыдущими версиями Paging. В частности, API Pager может использовать более старые объекты DataSource с помощью метода asPagingSourceFactory . Это означает, что у вас есть следующие варианты миграции:
- Вы можете перенести свой
DataSourceвPagingSource, но оставить остальную часть реализации постраничной навигации без изменений. - Вы можете перенести всю реализацию постраничной навигации, чтобы полностью перевести ваше приложение на Paging 3.
В разделах этой страницы объясняется, как перенести компоненты постраничной навигации на каждый уровень вашего приложения.
Классы DataSource
В этом разделе описаны все необходимые изменения для миграции более старой реализации Paging на использование PagingSource .
Классы PageKeyedDataSource , PositionalDataSource и ItemKeyedDataSource из Paging 2 объединены в API PagingSource в Paging 3. Методы загрузки из всех старых классов API объединены в один метод load в PagingSource . Это уменьшает дублирование кода, поскольку большая часть логики в методах загрузки в реализациях старых классов API часто идентична.
В разделе «Страничная навигация 3» все параметры метода загрузки заменяются закрытым классом LoadParams , который включает подклассы для каждого типа загрузки. Если вам необходимо различать типы загрузки в вашем методе load , проверьте, какой подкласс LoadParams был передан: LoadParams.Refresh , LoadParams.Prepend или LoadParams.Append .
Чтобы узнать больше о реализации PagingSource , см. раздел «Определение источника данных» .
Клавиши обновления
Реализации PagingSource должны определять, как возобновляется обновление с середины загруженных постраничных данных. Для этого необходимо реализовать getRefreshKey , который сопоставляет правильный начальный ключ, используя state.anchorPosition в качестве наиболее недавно использованного индекса.
// 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
}
Преобразования списков
В более старых версиях библиотеки Paging преобразование постраничных данных осуществляется с помощью следующих методов:
-
DataSource.map -
DataSource.mapByPage -
DataSource.Factory.map -
DataSource.Factory.mapByPage
В Paging 3 все преобразования применяются как операторы к PagingData . Если вы используете какой-либо из методов из приведенного выше списка для преобразования вашего постраничного списка, вам необходимо перенести логику преобразования из DataSource в PagingData при создании Pager с использованием вашего нового PagingSource .
Чтобы узнать больше о применении преобразований к постраничным данным с помощью Paging 3, см. раздел «Преобразование потоков данных» .
PagedList
В этом разделе описаны все необходимые изменения для миграции более старой реализации Paging на использование Pager и PagingData в Paging 3.
Классы PagedListBuilder
PagingData заменяет существующий PagedList из Paging 2. Для перехода на PagingData необходимо обновить следующее:
- Настройка пейджинга перенесена из
PagedList.Configв файлPagingConfig. - Более старые классы-конструкторы были объединены в один класс
Pager. -
Pagerпредоставляет наблюдаемыйFlow<PagingData>с его свойством.flow.
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)
Чтобы узнать больше о настройке реактивного потока объектов PagingData с использованием Paging 3, см. раздел «Настройка потока PagingData» .
BoundaryCallback для обработки многоуровневых источников
В Paging 3 RemoteMediator заменяет PagedList.BoundaryCallback в качестве обработчика для постраничной навигации из сети и базы данных.
Чтобы узнать больше об использовании RemoteMediator для переадресации страниц из сети и базы данных в Paging 3, см. практическое руководство по Android Paging .
LazyPagingItems
В этом разделе описаны все необходимые изменения для миграции более старой реализации постраничной навигации на использование LazyPagingItems из Paging 3.
Paging 3 предоставляет collectAsLazyPagingItems для обработки нового потока PagingData . Для миграции уровня представления используйте артефакт paging-compose и collectAsLazyPagingItems для сбора элементов PagingData и их отображения в функциях @Composable .
Чтобы узнать больше о LazyPagingItems , см. раздел «Загрузка и отображение постраничных данных» .
Сравнение списков и обновления
Если вы в настоящее время используете собственную логику сравнения списков, перейдите на использование LazyPagingItems предоставляемых в Paging 3. Чтобы гарантировать корректное сравнение, укажите ключ элемента в вашем ленивом списке:
@Composable
fun UserScreen(viewModel: UserViewModel) {
// Collects the Flow into a LazyPagingItems object
val lazyPagingItems = viewModel.pager.flow.collectAsLazyPagingItems()
UserList(lazyPagingItems)
}
@Composable
fun UserScreen(viewModel: UserViewModel) {
val lazyPagingItems = viewModel.pager.flow.collectAsLazyPagingItems()
UserList(lazyPagingItems)
}
@Composable
fun UserList(lazyPagingItems: LazyPagingItems<User>) {
LazyColumn {
items(
count = lazyPagingItems.itemCount,
// Provide a stable key for each item, similar to DiffUtil in Views
key = lazyPagingItems.itemKey { user -> user.id }
) { index ->
val user = lazyPagingItems[index]
if (user != null) {
UserRow(user = user)
}
}
}
}
Для получения дополнительной информации о ключах предметов см. раздел «Ключи предметов» .
Состояния загрузки
В Paging 3 вам не нужен отдельный адаптер для отображения заголовков или нижних колонтитулов для состояний загрузки. Объект LazyPagingItems предоставляет свойство loadState , которое вы можете проверить непосредственно в вашем LazyColumn .
LazyColumn {
// ... items(lazyPagingItems) go here ...
// Show loading spinner at bottom of list when appending data
if (lazyPagingItems.loadState.append is LoadState.Loading) {
item {
CircularProgressIndicator(modifier = Modifier.fillMaxWidth())
}
}
}
Дополнительные ресурсы
Чтобы узнать больше о библиотеке пейджинга, ознакомьтесь со следующими дополнительными ресурсами:
Документация
Просмотры контента
{% verbatim %}Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Загрузка и отображение постраничных данных
- Соберите постраничные данные
- Страница из сети и базы данных