Gromadzenie danych z podziałem na strony

Ten przewodnik opiera się na bibliotece stron internetowych omówię, w którym znajdziesz dostosować rozwiązanie do ładowania danych do architektury aplikacji do Twoich potrzeb.

Utwórz listę dostrzegalną

Zwykle w kodzie interfejsu użytkownika występują: LiveData<PagedList> (lub w przypadku używania RxJava2, Flowable<PagedList> lub Observable<PagedList>), który znajduje się w ViewModel aplikacji. Ten dostrzegalny obiekt tworzy połączenie między prezentacją a treścią danych o listach aplikacji.

Aby utworzyć jedną z tych obserwowalnych PagedList, przekaż wystąpienie DataSource.Factory do LivePagedListBuilder lub RxPagedListBuilder obiektu. Wczyta się obiekt DataSource stron dla pojedynczej wartości PagedList. Klasa fabryczna tworzy nowe instancje PagedList w odpowiedzi na aktualizacje treści, takie jak unieważnienia tabel bazy danych i odświeżania sieci. Trwałość sal biblioteka może zapewnić DataSource.Factory Możesz też utworzyć własny.

Fragment kodu poniżej pokazuje, jak utworzyć nowe wystąpienie LiveData<PagedList> w: zajęcia ViewModel w aplikacji za pomocą Sala DataSource.Factory-kompilacja funkcje:

Koncert Dao

KotlinJava
@Dao
interface ConcertDao {
   
// The Int type parameter tells Room to use a PositionalDataSource
   
// object, with position-based loading under the hood.
   
@Query("SELECT * FROM concerts ORDER BY date DESC")
   
fun concertsByDate(): DataSource.Factory<Int, Concert>
}
@Dao
public interface ConcertDao {
   
// The Integer type parameter tells Room to use a PositionalDataSource
   
// object, with position-based loading under the hood.
   
@Query("SELECT * FROM concerts ORDER BY date DESC")
   
DataSource.Factory<Integer, Concert> concertsByDate();
}

Model widoku koncertu

KotlinJava
// The Int type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Int, Concert> =
       concertDao
.concertsByDate()

val concertList = myConcertDataSource.toLiveData(pageSize = 50)
// The Integer type argument corresponds to a PositionalDataSource object.
DataSource.Factory<Integer, Concert> myConcertDataSource =
       concertDao
.concertsByDate();

LiveData<PagedList<Concert>> concertList =
       
LivePagedListBuilder(myConcertDataSource, /* page size */ 50).build();

Definiowanie własnej konfiguracji stronicowania

Aby bardziej szczegółowo skonfigurować LiveData<PagedList> – zaawansowane możesz też zdefiniować własną konfigurację stronicowania. Możesz na przykład: zdefiniować następujące atrybuty:

Jeśli chcesz mieć większą kontrolę nad tym, kiedy biblioteka stron internetowych wczytuje listę z do bazy danych aplikacji, przekazywać niestandardowe Executor w tabeli LivePagedListBuilder, Jak widać w tym fragmencie kodu:

Model widoku koncertu

KotlinJava
val myPagingConfig = Config(
        pageSize
= 50,
        prefetchDistance
= 150,
        enablePlaceholders
= true
)

// The Int type argument corresponds to a PositionalDataSource object.
val myConcertDataSource : DataSource.Factory<Int, Concert> =
        concertDao
.concertsByDate()

val concertList = myConcertDataSource.toLiveData(
        pagingConfig
= myPagingConfig,
        fetchExecutor
= myExecutor
)
PagedList.Config myPagingConfig = new PagedList.Config.Builder()
       
.setPageSize(50)
       
.setPrefetchDistance(150)
       
.setEnablePlaceholders(true)
       
.build();

// The Integer type argument corresponds to a PositionalDataSource object.
DataSource.Factory<Integer, Concert> myConcertDataSource =
        concertDao
.concertsByDate();

LiveData<PagedList<Concert>> concertList =
       
new LivePagedListBuilder<>(myConcertDataSource, myPagingConfig)
           
.setFetchExecutor(myExecutor)
           
.build();

Wybór odpowiedniego typu źródła danych

Ważne jest połączenie ze źródłem danych, które najlepiej go obsługuje struktura danych:

  • Używaj PageKeyedDataSource, jeśli wczytywane strony, umieść klawisze następny/poprzedni. Na przykład, jeśli pobierasz dane z mediów społecznościowych, postów w mediach społecznościowych z sieci, konieczne może być przekazanie tokena nextPage z jednego do kolejnego wczytywania.
  • Używaj ItemKeyedDataSource, jeśli musisz użyć danych z elementu N, aby pobrać element N+1. Jeśli na przykład pobierasz komentarze z wątkami w przypadku aplikacji do dyskusji, konieczne może być przekazanie identyfikatora od ostatniego komentarza, aby pobrać zawartość następnego.
  • Używaj PositionalDataSource, jeśli możesz pobierać strony z danymi z dowolnej lokalizacji, którą wybierzesz w magazynie danych. Ta klasa obsługuje żądania zbioru elementów danych zaczynających się od dowolnej lokalizację. Żądanie może na przykład zwrócić 50 elementów danych zaczynając od lokalizacji 1500.

Powiadamiaj o nieprawidłowych danych

W przypadku korzystania z biblioteki stronicowania warstwa danych ma obowiązek powiadamiać w innych warstwach aplikacji, gdy tabela lub wiersz stają się nieaktualne. Aby to zrobić, zadzwoń: invalidate() z DataSource zajęcia, które masz wybrane dla Twojej aplikacji.

Tworzenie własnych źródeł danych

Jeśli używasz niestandardowego rozwiązania do obsługi danych lokalnych lub wczytujesz dane bezpośrednio z możesz zastosować jedną z funkcji DataSource. następujący fragment kodu wskazuje źródło danych powiązane z godzina rozpoczęcia:

KotlinJava
class ConcertTimeDataSource() :
       
ItemKeyedDataSource<Date, Concert>() {
   
override fun getKey(item: Concert) = item.startTime

   
override fun loadInitial(
            params
: LoadInitialParams<Date>,
            callback
: LoadInitialCallback<Concert>) {
       
val items = fetchItems(params.requestedInitialKey,
                params
.requestedLoadSize)
        callback
.onResult(items)
   
}

   
override fun loadAfter(
            params
: LoadParams<Date>,
            callback
: LoadCallback<Concert>) {
       
val items = fetchItemsAfter(
            date
= params.key,
            limit
= params.requestedLoadSize)
        callback
.onResult(items)
   
}
}
public class ConcertTimeDataSource
       
extends ItemKeyedDataSource<Date, Concert> {
   
@NonNull
   
@Override
   
public Date getKey(@NonNull Concert item) {
       
return item.getStartTime();
   
}

   
@Override
   
public void loadInitial(@NonNull LoadInitialParams<Date> params,
           
@NonNull LoadInitialCallback<Concert> callback) {
       
List<Concert> items =
            fetchItems
(params.key, params.requestedLoadSize);
        callback
.onResult(items);
   
}

   
@Override
   
public void loadAfter(@NonNull LoadParams<Date> params,
           
@NonNull LoadCallback<Concert> callback) {
       
List<Concert> items =
            fetchItemsAfter
(params.key, params.requestedLoadSize);
        callback
.onResult(items);
   
}

Następnie możesz wczytać te dostosowane dane do obiektów PagedList, tworząc konkretny podklasa DataSource.Factory ten fragment kodu pokazuje, jak generować nowe wystąpienia danych niestandardowych źródła zdefiniowanego w poprzednim fragmencie kodu:

KotlinJava
class ConcertTimeDataSourceFactory :
       
DataSource.Factory<Date, Concert>() {
   
val sourceLiveData = MutableLiveData<ConcertTimeDataSource>()
   
var latestSource: ConcertDataSource?
   
override fun create(): DataSource<Date, Concert> {
        latestSource
= ConcertTimeDataSource()
        sourceLiveData
.postValue(latestSource)
       
return latestSource
   
}
}
public class ConcertTimeDataSourceFactory
       
extends DataSource.Factory<Date, Concert> {
   
private MutableLiveData<ConcertTimeDataSource> sourceLiveData =
           
new MutableLiveData<>();

   
private ConcertDataSource latestSource;

   
@Override
   
public DataSource<Date, Concert> create() {
        latestSource
= new ConcertTimeDataSource();
        sourceLiveData
.postValue(latestSource);
       
return latestSource;
   
}
}

Zastanów się, jak działają aktualizacje treści

Podczas tworzenia modułu dostrzegalnego PagedList, zobacz, jak i aktualizacje treści. Jeśli wczytujesz dane bezpośrednio z pokoju aktualizacje bazy danych są przekazywane do interfejsu aplikacji automatycznie.

Korzystając z interfejsu API sieci z pozycją na stronach, zwykle występuje interakcja z użytkownikiem, na przykład: „przesuń, aby odświeżyć”, są sygnałem do unieważnienia DataSource, z których korzystasz najczęściej w ostatnim czasie. Następnie wysyłasz prośbę o nowe wystąpienie tego źródła danych. Obserwujący fragment kodu ilustruje takie działanie:

KotlinJava
class ConcertActivity : AppCompatActivity() {
   
override fun onCreate(savedInstanceState: Bundle?) {
       
// ...
       
concertTimeViewModel.refreshState.observe(this, Observer {
           
// Shows one possible way of triggering a refresh operation.
            swipeRefreshLayout
.isRefreshing =
                    it
== MyNetworkState.LOADING
       
})
        swipeRefreshLayout
.setOnRefreshListener {
            concertTimeViewModel
.invalidateDataSource()
       
}

   
}
}

class ConcertTimeViewModel(firstConcertStartTime: Date) : ViewModel() {
   
val dataSourceFactory = ConcertTimeDataSourceFactory(firstConcertStartTime)
   
val concertList: LiveData<PagedList<Concert>> =
            dataSourceFactory
.toLiveData(
                pageSize
= 50,
                fetchExecutor
= myExecutor
           
)

   
fun invalidateDataSource() =
            dataSourceFactory
.sourceLiveData.value?.invalidate()

}
public class ConcertActivity extends AppCompatActivity {
   
@Override
   
public void onCreate(@Nullable Bundle savedInstanceState) {
       
// ...
       
viewModel.getRefreshState()
               
.observe(this, new Observer<NetworkState>() {
           
// Shows one possible way of triggering a refresh operation.
           
@Override
           
public void onChanged(@Nullable MyNetworkState networkState) {
                swipeRefreshLayout
.isRefreshing =
                        networkState
== MyNetworkState.LOADING;
           
}
       
};

        swipeRefreshLayout
.setOnRefreshListener(new SwipeRefreshListener() {
           
@Override
           
public void onRefresh() {
                viewModel
.invalidateDataSource();
           
}
       
});

   
}
}

public class ConcertTimeViewModel extends ViewModel {
   
private LiveData<PagedList<Concert>> concertList;
   
private DataSource<Date, Concert> mostRecentDataSource;

   
public ConcertTimeViewModel(Date firstConcertStartTime) {
       
ConcertTimeDataSourceFactory dataSourceFactory =
               
new ConcertTimeDataSourceFactory(firstConcertStartTime);
        mostRecentDataSource
= dataSourceFactory.create();
        concertList
= new LivePagedListBuilder<>(dataSourceFactory, 50)
               
.setFetchExecutor(myExecutor)
               
.build();
   
}

   
public void invalidateDataSource() {
        mostRecentDataSource
.invalidate();
   
}

}

Dodaj mapowanie danych

Biblioteka stron docelowych obsługuje przekształcanie elementów na podstawie elementów i stron wczytany przez DataSource.

W poniższym fragmencie kodu połączenie nazwy koncertu i daty koncertu to mapowane na jeden ciąg zawierający zarówno nazwę, jak i datę:

KotlinJava
class ConcertViewModel : ViewModel() {
   
val concertDescriptions : LiveData<PagedList<String>>
       
init {
           
val concerts = database.allConcertsFactory()
                   
.map { "${it.name} - ${it.date}" }
                   
.toLiveData(pageSize = 50)
       
}
}
public class ConcertViewModel extends ViewModel {
   
private LiveData<PagedList<String>> concertDescriptions;

   
public ConcertViewModel(MyDatabase database) {
       
DataSource.Factory<Integer, Concert> factory =
                database
.allConcertsFactory().map(concert ->
                    concert
.getName() + "-" + concert.getDate());
        concertDescriptions
= new LivePagedListBuilder<>(
            factory
, /* page size */ 50).build();
   
}
}

Jest to przydatne, jeśli chcesz pakować, przekonwertować lub przygotować produkty po ich wczytano. Ponieważ operacja jest wykonywana na wykonawcy pobierania, możesz potencjalnie kosztowną pracę, taką jak odczyt z dysku lub wykonywanie zapytań do oddzielnej bazy danych.

Prześlij opinię

Podziel się z nami swoimi opiniami i pomysłami, korzystając z tych zasobów:

Narzędzie do śledzenia błędów
Zgłoś problemy, abyśmy mogli je naprawić.

Dodatkowe materiały

Więcej informacji o bibliotece stronicowania znajdziesz w poniższe zasoby.

Próbki

Ćwiczenia z programowania

Filmy

.

Obecnie nie ma rekomendacji.

na swoje konto Google.