Migrate to Paging 3 (Migracja do strony 3)

Biblioteka Paging 3 znacznie różni się od wcześniejszych wersji biblioteki Paging. Ta wersja zapewnia ulepszoną funkcjonalność, najwyższej klasy obsługę współprogramów Kotlin i Flow oraz płynną integrację z Jetpack Compose.

Korzyści z przejścia na bibliotekę Paging 3

Biblioteka Paging 3 zawiera te funkcje, które nie były dostępne we wcześniejszych wersjach:

  • Pierwszorzędna obsługa korutyn w języku Kotlin i Flow.
  • Wbudowane sygnały stanu wczytywania i błędu do projektowania responsywnego interfejsu, w tym funkcje ponawiania i odświeżania.
  • Ulepszenia warstwy repozytorium, w tym obsługa anulowania i uproszczony interfejs źródła danych.
  • Ulepszenia warstwy prezentacji, separatorów list, niestandardowych przekształceń stron, nagłówków i stopek oraz elementów stanu wczytywania dla list wczytywanych z opóźnieniem.

Przenoszenie aplikacji do biblioteki Paging 3

Aby w pełni przejść na bibliotekę Paging 3, musisz przenieść z biblioteki Paging 2 te główne komponenty:

  • DataSource zajęć
  • PagedList
  • Warstwa prezentacji (do LazyPagingItems)

Niektóre komponenty biblioteki Paging 3 są jednak wstecznie zgodne z poprzednimi wersjami biblioteki Paging. W szczególności interfejs API Pager może używać starszych obiektów DataSource z metodą asPagingSourceFactory. Oznacza to, że masz do wyboru te opcje migracji:

  • Możesz przenieść DataSource do PagingSource, ale resztę implementacji stronicowania pozostawić bez zmian.
  • Możesz przenieść całą implementację biblioteki Paging, aby w pełni zmigrować aplikację do biblioteki Paging 3.

W sekcjach na tej stronie znajdziesz informacje o tym, jak migrować komponenty biblioteki Paging w poszczególnych warstwach aplikacji.

DataSource zajęć

W tej sekcji opisano wszystkie niezbędne zmiany, które należy wprowadzić, aby przenieść starszą implementację stronicowania na PagingSource.

Interfejsy PageKeyedDataSource, PositionalDataSourceItemKeyedDataSource z biblioteki Paging 2 zostały połączone w interfejs PagingSource w bibliotece Paging 3. Metody wczytywania ze wszystkich starych klas interfejsu API są połączone w jedną metodę load w klasie PagingSource. Zmniejsza to duplikowanie kodu, ponieważ większość logiki w metodach wczytywania w implementacjach starych klas interfejsu API jest często identyczna.

W bibliotece Paging 3 wszystkie parametry metody wczytywania są zastępowane przez LoadParams klasę zamkniętą, która zawiera podklasy dla każdego typu wczytywania. Jeśli chcesz rozróżniać typy wczytywania w metodzie load, sprawdź, która podklasa LoadParams została przekazana: LoadParams.Refresh, LoadParams.Prepend lub LoadParams.Append.

Więcej informacji o implementacji PagingSource znajdziesz w artykule Definiowanie źródła danych.

Odśwież klucze

Implementacje PagingSource muszą określać, jak odświeżanie ma być wznawiane od środka załadowanych danych strony. Aby to zrobić, zaimplementuj getRefreshKey w celu zmapowania prawidłowego klucza początkowego przy użyciu state.anchorPosition jako ostatnio użytego indeksu.

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

Wyświetlanie listy przekształceń

W starszych wersjach biblioteki Paging przekształcanie danych podzielonych na strony opiera się na tych metodach:

  • DataSource.map
  • DataSource.mapByPage
  • DataSource.Factory.map
  • DataSource.Factory.mapByPage

W bibliotece Paging 3 wszystkie przekształcenia są stosowane jako operatory na obiekcie PagingData. Jeśli do przekształcenia listy podzielonej na strony używasz którejkolwiek z metod z powyższej listy, musisz przenieść logikę przekształcania z DataSource do PagingData podczas tworzenia Pager za pomocą nowego PagingSource.

Więcej informacji o stosowaniu przekształceń do danych podzielonych na strony za pomocą biblioteki Paging 3 znajdziesz w artykule Przekształcanie strumieni danych.

PagedList

W tej sekcji opisujemy wszystkie niezbędne zmiany, które należy wprowadzić, aby przenieść starszą implementację biblioteki Paging na Paging 3, w której używane są adnotacje PagerPagingData.

PagedListBuilder zajęć

PagingData zastępuje dotychczasowy element PagedList z Paging 2. Aby przejść na PagingData, musisz zaktualizować te elementy:

  • Konfiguracja stronicowania została przeniesiona z PagedList.Config do PagingConfig.
  • Starsze klasy konstruktorów zostały połączone w jedną klasę Pager.
  • Pager udostępnia obserwowalną właściwość Flow<PagingData> z właściwością .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)

Więcej informacji o konfigurowaniu reaktywnego strumienia obiektów PagingData za pomocą biblioteki Paging 3 znajdziesz w artykule Konfigurowanie strumienia PagingData.

BoundaryCallback w przypadku źródeł warstwowych

W bibliotece Paging 3 RemoteMediator zastępuje PagedList.BoundaryCallback jako moduł obsługi stronicowania z sieci i bazy danych.

Więcej informacji o używaniu RemoteMediator do stronicowania z sieci i bazy danych w bibliotece Paging 3 znajdziesz w ćwiczeniach z programowania dotyczących stronicowania na Androidzie.

LazyPagingItems

W tej sekcji opisujemy wszystkie niezbędne zmiany, które należy wprowadzić, aby przenieść starszą implementację biblioteki Paging na wersję LazyPagingItems z biblioteki Paging 3.

Biblioteka Paging 3 udostępnia collectAsLazyPagingItems do obsługi nowego przepływu PagingData. Aby przenieść warstwę prezentacji, użyj artefaktu paging-composecollectAsLazyPagingItems, aby zebrać elementy PagingData i wyświetlić je w funkcjach @Composable.

Więcej informacji o LazyPagingItems znajdziesz w artykule Wczytywanie i wyświetlanie danych podzielonych na strony.

Porównywanie list i aktualizacje

Jeśli obecnie używasz niestandardowej logiki różnicowania list, przenieś implementację, aby zamiast niej używać funkcji LazyPagingItems udostępnionej w bibliotece Paging 3. Aby zapewnić prawidłowe porównywanie, określ klucz elementu na liście leniwej:

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

Więcej informacji o kluczach elementów znajdziesz w artykule Klucze elementów.

Wczytuję stany

W bibliotece Paging 3 nie potrzebujesz osobnego adaptera do wyświetlania nagłówków lub stopek w przypadku stanów wczytywania. Obiekt LazyPagingItems udostępnia właściwość loadState, którą możesz sprawdzić bezpośrednio w 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())
        }
    }
}

Dodatkowe materiały

Więcej informacji o bibliotece Paging znajdziesz w tych materiałach:

Dokumentacja

Wyświetlanie treści