diff --git a/app/build.gradle b/app/build.gradle index 430ba3af17..e0e5740eff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -223,7 +223,6 @@ configurations.all { // lifecycle-livedata: ComputableLiveData, MediatorLiveData, Transformations // lifecycle-livedata-core: LiveData, MutableLiveData, Observer - // paging-runtime: AsyncPagedListDiffer, LivePagedListBuilder, PagedListAdapter, PagedStorageDiffHelper } dependencies { @@ -323,7 +322,7 @@ dependencies { // https://mvnrepository.com/artifact/androidx.paging/paging-runtime // https://developer.android.com/jetpack/androidx/releases/paging - //implementation "androidx.paging:paging-runtime:$paging_version" + implementation "androidx.paging:paging-runtime:$paging_version" // https://mvnrepository.com/artifact/androidx.preference/preference implementation "androidx.preference:preference:$preference_version" diff --git a/app/src/main/java/androidx/paging/AsyncPagedListDiffer.java b/app/src/main/java/androidx/paging/AsyncPagedListDiffer.java deleted file mode 100644 index 6640dc0c8c..0000000000 --- a/app/src/main/java/androidx/paging/AsyncPagedListDiffer.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.paging; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.arch.core.executor.ArchTaskExecutor; -import androidx.lifecycle.LiveData; -import androidx.recyclerview.widget.AdapterListUpdateCallback; -import androidx.recyclerview.widget.AsyncDifferConfig; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ListUpdateCallback; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executor; - -/** - * Helper object for mapping a {@link PagedList} into a - * {@link androidx.recyclerview.widget.RecyclerView.Adapter RecyclerView.Adapter}. - *
- * For simplicity, the {@link PagedListAdapter} wrapper class can often be used instead of the - * differ directly. This diff class is exposed for complex cases, and where overriding an adapter - * base class to support paging isn't convenient. - *
- * When consuming a {@link LiveData} of PagedList, you can observe updates and dispatch them - * directly to {@link #submitList(PagedList)}. The AsyncPagedListDiffer then can present this - * updating data set simply for an adapter. It listens to PagedList loading callbacks, and uses - * DiffUtil on a background thread to compute updates as new PagedLists are received. - *
- * It provides a simple list-like API with {@link #getItem(int)} and {@link #getItemCount()} for an - * adapter to acquire and present data objects. - *
- * A complete usage pattern with Room would look like this: - *
- * {@literal @}Dao - * interface UserDao { - * {@literal @}Query("SELECT * FROM user ORDER BY lastName ASC") - * public abstract DataSource.Factory<Integer, User> usersByLastName(); - * } - * - * class MyViewModel extends ViewModel { - * public final LiveData<PagedList<User>> usersList; - * public MyViewModel(UserDao userDao) { - * usersList = new LivePagedListBuilder<>( - * userDao.usersByLastName(), /* page size {@literal *}/ 20).build(); - * } - * } - * - * class MyActivity extends AppCompatActivity { - * {@literal @}Override - * public void onCreate(Bundle savedState) { - * super.onCreate(savedState); - * MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class); - * RecyclerView recyclerView = findViewById(R.id.user_list); - * final UserAdapter adapter = new UserAdapter(); - * viewModel.usersList.observe(this, pagedList -> adapter.submitList(pagedList)); - * recyclerView.setAdapter(adapter); - * } - * } - * - * class UserAdapter extends RecyclerView.Adapter<UserViewHolder> { - * private final AsyncPagedListDiffer<User> mDiffer - * = new AsyncPagedListDiffer(this, DIFF_CALLBACK); - * {@literal @}Override - * public int getItemCount() { - * return mDiffer.getItemCount(); - * } - * public void submitList(PagedList<User> pagedList) { - * mDiffer.submitList(pagedList); - * } - * {@literal @}Override - * public void onBindViewHolder(UserViewHolder holder, int position) { - * User user = mDiffer.getItem(position); - * if (user != null) { - * holder.bindTo(user); - * } else { - * // Null defines a placeholder item - AsyncPagedListDiffer will automatically - * // invalidate this row when the actual object is loaded from the database - * holder.clear(); - * } - * } - * public static final DiffUtil.ItemCallback<User> DIFF_CALLBACK = - * new DiffUtil.ItemCallback<User>() { - * {@literal @}Override - * public boolean areItemsTheSame( - * {@literal @}NonNull User oldUser, {@literal @}NonNull User newUser) { - * // User properties may have changed if reloaded from the DB, but ID is fixed - * return oldUser.getId() == newUser.getId(); - * } - * {@literal @}Override - * public boolean areContentsTheSame( - * {@literal @}NonNull User oldUser, {@literal @}NonNull User newUser) { - * // NOTE: if you use equals, your object must properly override Object#equals() - * // Incorrectly returning false here will result in too many animations. - * return oldUser.equals(newUser); - * } - * } - * }- * - * @param
- * Note that this operates on both loaded items and null padding within the PagedList. - * - * @param index Index of item to get, must be >= 0, and < {@link #getItemCount()}. - * @return The item, or null, if a null placeholder is at the specified position. - */ - @SuppressWarnings("WeakerAccess") - @Nullable - public T getItem(int index) { - if (mPagedList == null) { - if (mSnapshot == null) { - throw new IndexOutOfBoundsException( - "Item count is zero, getItem() call is invalid"); - } else { - return mSnapshot.get(index); - } - } - - mPagedList.loadAround(index); - return mPagedList.get(index); - } - - /** - * Get the number of items currently presented by this Differ. This value can be directly - * returned to {@link RecyclerView.Adapter#getItemCount()}. - * - * @return Number of items being presented. - */ - @SuppressWarnings("WeakerAccess") - public int getItemCount() { - if (mPagedList != null) { - return mPagedList.size(); - } - - return mSnapshot == null ? 0 : mSnapshot.size(); - } - - /** - * Pass a new PagedList to the differ. - *
- * If a PagedList is already present, a diff will be computed asynchronously on a background
- * thread. When the diff is computed, it will be applied (dispatched to the
- * {@link ListUpdateCallback}), and the new PagedList will be swapped in as the
- * {@link #getCurrentList() current list}.
- *
- * @param pagedList The new PagedList.
- */
- public void submitList(@Nullable final PagedList
- * If a PagedList is already present, a diff will be computed asynchronously on a background
- * thread. When the diff is computed, it will be applied (dispatched to the
- * {@link ListUpdateCallback}), and the new PagedList will be swapped in as the
- * {@link #getCurrentList() current list}.
- *
- * The commit callback can be used to know when the PagedList is committed, but note that it
- * may not be executed. If PagedList B is submitted immediately after PagedList A, and is
- * committed directly, the callback associated with PagedList A will not be run.
- *
- * @param pagedList The new PagedList.
- * @param commitCallback Optional runnable that is executed when the PagedList is committed, if
- * it is committed.
- */
- @SuppressWarnings("ReferenceEquality")
- public void submitList(@Nullable final PagedList
- * This is not necessarily the most recent list passed to {@link #submitList(PagedList)},
- * because a diff is computed asynchronously between the new list and the current list before
- * updating the currentList value. May be null if no PagedList is being presented.
- *
- * @return The list currently being displayed, may be null.
- */
- @SuppressWarnings("WeakerAccess")
- @Nullable
- public PagedList
- * Position may not match passed item's position - if trying to query the key from a position
- * that isn't yet loaded, a fallback item (last loaded item accessed) will be passed.
- */
- abstract Key getKey(int position, Value item);
-
- boolean supportsPageDropping() {
- return true;
- }
-}
diff --git a/app/src/main/java/androidx/paging/ContiguousPagedList.java b/app/src/main/java/androidx/paging/ContiguousPagedList.java
deleted file mode 100644
index 99060671d8..0000000000
--- a/app/src/main/java/androidx/paging/ContiguousPagedList.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.paging;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import androidx.annotation.AnyThread;
-import androidx.annotation.IntDef;
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.lang.annotation.Retention;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-class ContiguousPagedList
- * DataSource is queried to load pages of content into a {@link PagedList}. A PagedList can grow as
- * it loads more data, but the data loaded cannot be updated. If the underlying data set is
- * modified, a new PagedList / DataSource pair must be created to represent the new data.
- *
- * To control how and when a PagedList queries data from its DataSource, see
- * {@link PagedList.Config}. The Config object defines things like load sizes and prefetch distance.
- *
- * To page in data that doesn't update, you can create a single DataSource, and pass it to a single
- * PagedList. For example, loading from network when the network's paging API doesn't provide
- * updates.
- *
- * To page in data from a source that does provide updates, you can create a
- * {@link DataSource.Factory}, where each DataSource created is invalidated when an update to the
- * data set occurs that makes the current snapshot invalid. For example, when paging a query from
- * the Database, and the table being queried inserts or removes items. You can also use a
- * DataSource.Factory to provide multiple versions of network-paged lists. If reloading all content
- * (e.g. in response to an action like swipe-to-refresh) is required to get a new version of data,
- * you can connect an explicit refresh signal to call {@link #invalidate()} on the current
- * DataSource.
- *
- * If you have more granular update signals, such as a network API signaling an update to a single
- * item in the list, it's recommended to load data from network into memory. Then present that
- * data to the PagedList via a DataSource that wraps an in-memory snapshot. Each time the in-memory
- * copy changes, invalidate the previous DataSource, and a new one wrapping the new state of the
- * snapshot can be created.
- *
- * Use {@link PageKeyedDataSource} if pages you load embed keys for loading adjacent pages. For
- * example a network response that returns some items, and a next/previous page links.
- *
- * Use {@link ItemKeyedDataSource} if you need to use data from item {@code N-1} to load item
- * {@code N}. For example, if requesting the backend for the next comments in the list
- * requires the ID or timestamp of the most recent loaded comment, or if querying the next users
- * from a name-sorted database query requires the name and unique ID of the previous.
- *
- * Use {@link PositionalDataSource} if you can load pages of a requested size at arbitrary
- * positions, and provide a fixed item count. PositionalDataSource supports querying pages at
- * arbitrary positions, so can provide data to PagedLists in arbitrary order. Note that
- * PositionalDataSource is required to respect page size for efficient tiling. If you want to
- * override page size (e.g. when network page size constraints are only known at runtime), use one
- * of the other DataSource classes.
- *
- * Because a {@code null} item indicates a placeholder in {@link PagedList}, DataSource may not
- * return {@code null} items in lists that it loads. This is so that users of the PagedList
- * can differentiate unloaded placeholder items from content that has been paged in.
- *
- * @param
- * Data-loading systems of an application or library can implement this interface to allow
- * {@code LiveData
- * The DataSource should invalidate itself if the snapshot is no longer valid. If a
- * DataSource becomes invalid, the only way to query more data is to create a new DataSource
- * from the Factory.
- *
- * {@link LivePagedListBuilder} for example will construct a new PagedList and DataSource
- * when the current DataSource is invalidated, and pass the new PagedList through the
- * {@code LiveData
- * Same as {@link #mapByPage(Function)}, but operates on individual items.
- *
- * @param function Function that runs on each loaded item, returning items of a potentially
- * new type.
- * @param
- * Same as {@link #map(Function)}, but allows for batch conversions.
- *
- * @param function Function that runs on each loaded page, returning items of a potentially
- * new type.
- * @param
- * Same as {@link #map(Function)}, but allows for batch conversions.
- *
- * @param function Function that runs on each loaded page, returning items of a potentially
- * new type.
- * @param
- * Same as {@link #mapByPage(Function)}, but operates on individual items.
- *
- * @param function Function that runs on each loaded item, returning items of a potentially
- * new type.
- * @param
- * Used to signal when a DataSource a data source has become invalid, and that a new data source
- * is needed to continue loading data.
- */
- public interface InvalidatedCallback {
- /**
- * Called when the data backing the list has become invalid. This callback is typically used
- * to signal that a new data source is needed.
- *
- * This callback will be invoked on the thread that calls {@link #invalidate()}. It is valid
- * for the data source to invalidate itself during its load methods, or for an outside
- * source to invalidate it.
- */
- @AnyThread
- void onInvalidated();
- }
-
- private AtomicBoolean mInvalid = new AtomicBoolean(false);
-
- private CopyOnWriteArrayList
- * Once invalidated, a data source will not become valid again.
- *
- * A data source will only invoke its callbacks once - the first time {@link #invalidate()}
- * is called, on that thread.
- *
- * @param onInvalidatedCallback The callback, will be invoked on thread that
- * {@link #invalidate()} is called on.
- */
- @AnyThread
- @SuppressWarnings("WeakerAccess")
- public void addInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
- mOnInvalidatedCallbacks.add(onInvalidatedCallback);
- }
-
- /**
- * Remove a previously added invalidate callback.
- *
- * @param onInvalidatedCallback The previously added callback.
- */
- @AnyThread
- @SuppressWarnings("WeakerAccess")
- public void removeInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
- mOnInvalidatedCallbacks.remove(onInvalidatedCallback);
- }
-
- /**
- * Signal the data source to stop loading, and notify its callback.
- *
- * If invalidate has already been called, this method does nothing.
- */
- @AnyThread
- public void invalidate() {
- if (mInvalid.compareAndSet(false, true)) {
- for (InvalidatedCallback callback : mOnInvalidatedCallbacks) {
- callback.onInvalidated();
- }
- }
- }
-
- /**
- * Returns true if the data source is invalid, and can no longer be queried for data.
- *
- * @return True if the data source is invalid, and can no longer return data.
- */
- @WorkerThread
- public boolean isInvalid() {
- return mInvalid.get();
- }
-}
diff --git a/app/src/main/java/androidx/paging/ItemKeyedDataSource.java b/app/src/main/java/androidx/paging/ItemKeyedDataSource.java
deleted file mode 100644
index 2e89ba6764..0000000000
--- a/app/src/main/java/androidx/paging/ItemKeyedDataSource.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.paging;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.arch.core.util.Function;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Incremental data loader for paging keyed content, where loaded content uses previously loaded
- * items as input to future loads.
- *
- * Implement a DataSource using ItemKeyedDataSource if you need to use data from item {@code N - 1}
- * to load item {@code N}. This is common, for example, in sorted database queries where
- * attributes of the item such just before the next query define how to execute it.
- *
- * The {@code InMemoryByItemRepository} in the
- * PagingWithNetworkSample
- * shows how to implement a network ItemKeyedDataSource using
- * Retrofit, while
- * handling swipe-to-refresh, network errors, and retry.
- *
- * @param
- * Note that this key is generally a hint, and may be ignored if you want to always load
- * from the beginning.
- */
- @Nullable
- public final Key requestedInitialKey;
-
- /**
- * Requested number of items to load.
- *
- * Note that this may be larger than available data.
- */
- public final int requestedLoadSize;
-
- /**
- * Defines whether placeholders are enabled, and whether the total count passed to
- * {@link LoadInitialCallback#onResult(List, int, int)} will be ignored.
- */
- public final boolean placeholdersEnabled;
-
-
- public LoadInitialParams(@Nullable Key requestedInitialKey, int requestedLoadSize,
- boolean placeholdersEnabled) {
- this.requestedInitialKey = requestedInitialKey;
- this.requestedLoadSize = requestedLoadSize;
- this.placeholdersEnabled = placeholdersEnabled;
- }
- }
-
- /**
- * Holder object for inputs to {@link #loadBefore(LoadParams, LoadCallback)}
- * and {@link #loadAfter(LoadParams, LoadCallback)}.
- *
- * @param
- * Returned data must begin directly adjacent to this position.
- */
- @NonNull
- public final Key key;
- /**
- * Requested number of items to load.
- *
- * Returned page can be of this size, but it may be altered if that is easier, e.g. a
- * network data source where the backend defines page size.
- */
- public final int requestedLoadSize;
-
- public LoadParams(@NonNull Key key, int requestedLoadSize) {
- this.key = key;
- this.requestedLoadSize = requestedLoadSize;
- }
- }
-
- /**
- * Callback for {@link #loadInitial(LoadInitialParams, LoadInitialCallback)}
- * to return data and, optionally, position/count information.
- *
- * A callback can be called only once, and will throw if called again.
- *
- * If you can compute the number of items in the data set before and after the loaded range,
- * call the three parameter {@link #onResult(List, int, int)} to pass that information. You
- * can skip passing this information by calling the single parameter {@link #onResult(List)},
- * either if it's difficult to compute, or if {@link LoadInitialParams#placeholdersEnabled} is
- * {@code false}, so the positioning information will be ignored.
- *
- * It is always valid for a DataSource loading method that takes a callback to stash the
- * callback and call it later. This enables DataSources to be fully asynchronous, and to handle
- * temporary, recoverable error states (such as a network error that can be retried).
- *
- * @param
- * Call this method from your DataSource's {@code loadInitial} function to return data,
- * and inform how many placeholders should be shown before and after. If counting is cheap
- * to compute (for example, if a network load returns the information regardless), it's
- * recommended to pass data back through this method.
- *
- * It is always valid to pass a different amount of data than what is requested. Pass an
- * empty list if there is no more data to load.
- *
- * @param data List of items loaded from the DataSource. If this is empty, the DataSource
- * is treated as empty, and no further loads will occur.
- * @param position Position of the item at the front of the list. If there are {@code N}
- * items before the items in data that can be loaded from this DataSource,
- * pass {@code N}.
- * @param totalCount Total number of items that may be returned from this DataSource.
- * Includes the number in the initial {@code data} parameter
- * as well as any items that can be loaded in front or behind of
- * {@code data}.
- */
- public abstract void onResult(@NonNull List
- * A callback can be called only once, and will throw if called again.
- *
- * It is always valid for a DataSource loading method that takes a callback to stash the
- * callback and call it later. This enables DataSources to be fully asynchronous, and to handle
- * temporary, recoverable error states (such as a network error that can be retried).
- *
- * @param
- * Call this method from your ItemKeyedDataSource's
- * {@link #loadBefore(LoadParams, LoadCallback)} and
- * {@link #loadAfter(LoadParams, LoadCallback)} methods to return data.
- *
- * Call this from {@link #loadInitial(LoadInitialParams, LoadInitialCallback)} to
- * initialize without counting available data, or supporting placeholders.
- *
- * It is always valid to pass a different amount of data than what is requested. Pass an
- * empty list if there is no more data to load.
- *
- * @param data List of items loaded from the ItemKeyedDataSource.
- */
- public abstract void onResult(@NonNull List
- * This method is called first to initialize a PagedList with data. If it's possible to count
- * the items that can be loaded by the DataSource, it's recommended to pass the loaded data to
- * the callback via the three-parameter
- * {@link LoadInitialCallback#onResult(List, int, int)}. This enables PagedLists
- * presenting data from this source to display placeholders to represent unloaded items.
- *
- * {@link LoadInitialParams#requestedInitialKey} and {@link LoadInitialParams#requestedLoadSize}
- * are hints, not requirements, so they may be altered or ignored. Note that ignoring the
- * {@code requestedInitialKey} can prevent subsequent PagedList/DataSource pairs from
- * initializing at the same location. If your data source never invalidates (for example,
- * loading from the network without the network ever signalling that old data must be reloaded),
- * it's fine to ignore the {@code initialLoadKey} and always start from the beginning of the
- * data set.
- *
- * @param params Parameters for initial load, including initial key and requested size.
- * @param callback Callback that receives initial load data.
- */
- public abstract void loadInitial(@NonNull LoadInitialParams
- * It's valid to return a different list size than the page size if it's easier, e.g. if your
- * backend defines page sizes. It is generally safer to increase the number loaded than reduce.
- *
- * Data may be passed synchronously during the loadAfter method, or deferred and called at a
- * later time. Further loads going down will be blocked until the callback is called.
- *
- * If data cannot be loaded (for example, if the request is invalid, or the data would be stale
- * and inconsistent, it is valid to call {@link #invalidate()} to invalidate the data source,
- * and prevent further loading.
- *
- * @param params Parameters for the load, including the key to load after, and requested size.
- * @param callback Callback that receives loaded data.
- */
- public abstract void loadAfter(@NonNull LoadParams
- * It's valid to return a different list size than the page size if it's easier, e.g. if your
- * backend defines page sizes. It is generally safer to increase the number loaded than reduce.
- *
- * Note: Data returned will be prepended just before the key
- * passed, so if you vary size, ensure that the last item is adjacent to the passed key.
- *
- * Data may be passed synchronously during the loadBefore method, or deferred and called at a
- * later time. Further loads going up will be blocked until the callback is called.
- *
- * If data cannot be loaded (for example, if the request is invalid, or the data would be stale
- * and inconsistent, it is valid to call {@link #invalidate()} to invalidate the data source,
- * and prevent further loading.
- *
- * @param params Parameters for the load, including the key to load before, and requested size.
- * @param callback Callback that receives loaded data.
- */
- public abstract void loadBefore(@NonNull LoadParams
- * If your ItemKeyedDataSource is loading from a source that is sorted and loaded by a unique
- * integer ID, you would return {@code item.getID()} here. This key can then be passed to
- * {@link #loadBefore(LoadParams, LoadCallback)} or
- * {@link #loadAfter(LoadParams, LoadCallback)} to load additional items adjacent to the item
- * passed to this function.
- *
- * If your key is more complex, such as when you're sorting by name, then resolving collisions
- * with integer ID, you'll need to return both. In such a case you would use a wrapper class,
- * such as {@code Pair
- * The required parameters are in the constructor, so you can simply construct and build, or
- * optionally enable extra features (such as initial load key, or BoundaryCallback).
- *
- * @param
- * This method is a convenience for:
- *
- * When a new PagedList/DataSource pair is created after the first, it acquires a load key from
- * the previous generation so that data is loaded around the position already being observed.
- *
- * @param key Initial load key passed to the first PagedList/DataSource.
- * @return this
- */
- @NonNull
- public LivePagedListBuilder
- * Pass a BoundaryCallback to listen to when the PagedList runs out of data to load. If this
- * method is not called, or {@code null} is passed, you will not be notified when each
- * DataSource runs out of data to provide to its PagedList.
- *
- * If you are paging from a DataSource.Factory backed by local storage, you can set a
- * BoundaryCallback to know when there is no more information to page from local storage.
- * This is useful to page from the network when local storage is a cache of network data.
- *
- * Note that when using a BoundaryCallback with a {@code LiveData
- * If not set, defaults to the Arch components I/O thread pool.
- *
- * @param fetchExecutor Executor for fetching data from DataSources.
- * @return this
- */
- @SuppressWarnings("unused")
- @NonNull
- public LivePagedListBuilder
- * No work (such as loading) is done immediately, the creation of the first PagedList is is
- * deferred until the LiveData is observed.
- *
- * @return The LiveData of PagedLists
- */
- @NonNull
- @SuppressLint("RestrictedApi")
- public LiveData
- * Implement a DataSource using PageKeyedDataSource if you need to use data from page {@code N - 1}
- * to load page {@code N}. This is common, for example, in network APIs that include a next/previous
- * link or key with each page load.
- *
- * The {@code InMemoryByPageRepository} in the
- * PagingWithNetworkSample
- * shows how to implement a network PageKeyedDataSource using
- * Retrofit, while
- * handling swipe-to-refresh, network errors, and retry.
- *
- * @param
- * Note that this may be larger than available data.
- */
- public final int requestedLoadSize;
-
- /**
- * Defines whether placeholders are enabled, and whether the total count passed to
- * {@link LoadInitialCallback#onResult(List, int, int, Key, Key)} will be ignored.
- */
- public final boolean placeholdersEnabled;
-
-
- public LoadInitialParams(int requestedLoadSize, boolean placeholdersEnabled) {
- this.requestedLoadSize = requestedLoadSize;
- this.placeholdersEnabled = placeholdersEnabled;
- }
- }
-
- /**
- * Holder object for inputs to {@link #loadBefore(LoadParams, LoadCallback)} and
- * {@link #loadAfter(LoadParams, LoadCallback)}.
- *
- * @param
- * Returned data must begin directly adjacent to this position.
- */
- @NonNull
- public final Key key;
-
- /**
- * Requested number of items to load.
- *
- * Returned page can be of this size, but it may be altered if that is easier, e.g. a
- * network data source where the backend defines page size.
- */
- public final int requestedLoadSize;
-
- public LoadParams(@NonNull Key key, int requestedLoadSize) {
- this.key = key;
- this.requestedLoadSize = requestedLoadSize;
- }
- }
-
- /**
- * Callback for {@link #loadInitial(LoadInitialParams, LoadInitialCallback)}
- * to return data and, optionally, position/count information.
- *
- * A callback can be called only once, and will throw if called again.
- *
- * If you can compute the number of items in the data set before and after the loaded range,
- * call the five parameter {@link #onResult(List, int, int, Object, Object)} to pass that
- * information. You can skip passing this information by calling the three parameter
- * {@link #onResult(List, Object, Object)}, either if it's difficult to compute, or if
- * {@link LoadInitialParams#placeholdersEnabled} is {@code false}, so the positioning
- * information will be ignored.
- *
- * It is always valid for a DataSource loading method that takes a callback to stash the
- * callback and call it later. This enables DataSources to be fully asynchronous, and to handle
- * temporary, recoverable error states (such as a network error that can be retried).
- *
- * @param
- * Call this method from your DataSource's {@code loadInitial} function to return data,
- * and inform how many placeholders should be shown before and after. If counting is cheap
- * to compute (for example, if a network load returns the information regardless), it's
- * recommended to pass data back through this method.
- *
- * It is always valid to pass a different amount of data than what is requested. Pass an
- * empty list if there is no more data to load.
- *
- * @param data List of items loaded from the DataSource. If this is empty, the DataSource
- * is treated as empty, and no further loads will occur.
- * @param position Position of the item at the front of the list. If there are {@code N}
- * items before the items in data that can be loaded from this DataSource,
- * pass {@code N}.
- * @param totalCount Total number of items that may be returned from this DataSource.
- * Includes the number in the initial {@code data} parameter
- * as well as any items that can be loaded in front or behind of
- * {@code data}.
- */
- public abstract void onResult(@NonNull List
- * Call this from {@link #loadInitial(LoadInitialParams, LoadInitialCallback)} to
- * initialize without counting available data, or supporting placeholders.
- *
- * It is always valid to pass a different amount of data than what is requested. Pass an
- * empty list if there is no more data to load.
- *
- * @param data List of items loaded from the PageKeyedDataSource.
- * @param previousPageKey Key for page before the initial load result, or {@code null} if no
- * more data can be loaded before.
- * @param nextPageKey Key for page after the initial load result, or {@code null} if no
- * more data can be loaded after.
- */
- public abstract void onResult(@NonNull List
- * A callback can be called only once, and will throw if called again.
- *
- * It is always valid for a DataSource loading method that takes a callback to stash the
- * callback and call it later. This enables DataSources to be fully asynchronous, and to handle
- * temporary, recoverable error states (such as a network error that can be retried).
- *
- * @param
- * Call this method from your PageKeyedDataSource's
- * {@link #loadBefore(LoadParams, LoadCallback)} and
- * {@link #loadAfter(LoadParams, LoadCallback)} methods to return data.
- *
- * It is always valid to pass a different amount of data than what is requested. Pass an
- * empty list if there is no more data to load.
- *
- * Pass the key for the subsequent page to load to adjacentPageKey. For example, if you've
- * loaded a page in {@link #loadBefore(LoadParams, LoadCallback)}, pass the key for the
- * previous page, or {@code null} if the loaded page is the first. If in
- * {@link #loadAfter(LoadParams, LoadCallback)}, pass the key for the next page, or
- * {@code null} if the loaded page is the last.
- *
- * @param data List of items loaded from the PageKeyedDataSource.
- * @param adjacentPageKey Key for subsequent page load (previous page in {@link #loadBefore}
- * / next page in {@link #loadAfter}), or {@code null} if there are
- * no more pages to load in the current load direction.
- */
- public abstract void onResult(@NonNull List
- * This method is called first to initialize a PagedList with data. If it's possible to count
- * the items that can be loaded by the DataSource, it's recommended to pass the loaded data to
- * the callback via the three-parameter
- * {@link LoadInitialCallback#onResult(List, int, int, Object, Object)}. This enables PagedLists
- * presenting data from this source to display placeholders to represent unloaded items.
- *
- * {@link LoadInitialParams#requestedLoadSize} is a hint, not a requirement, so it may be may be
- * altered or ignored.
- *
- * @param params Parameters for initial load, including requested load size.
- * @param callback Callback that receives initial load data.
- */
- public abstract void loadInitial(@NonNull LoadInitialParams
- * It's valid to return a different list size than the page size if it's easier, e.g. if your
- * backend defines page sizes. It is generally safer to increase the number loaded than reduce.
- *
- * Data may be passed synchronously during the load method, or deferred and called at a
- * later time. Further loads going down will be blocked until the callback is called.
- *
- * If data cannot be loaded (for example, if the request is invalid, or the data would be stale
- * and inconsistent, it is valid to call {@link #invalidate()} to invalidate the data source,
- * and prevent further loading.
- *
- * @param params Parameters for the load, including the key for the new page, and requested load
- * size.
- * @param callback Callback that receives loaded data.
- */
- public abstract void loadBefore(@NonNull LoadParams
- * It's valid to return a different list size than the page size if it's easier, e.g. if your
- * backend defines page sizes. It is generally safer to increase the number loaded than reduce.
- *
- * Data may be passed synchronously during the load method, or deferred and called at a
- * later time. Further loads going down will be blocked until the callback is called.
- *
- * If data cannot be loaded (for example, if the request is invalid, or the data would be stale
- * and inconsistent, it is valid to call {@link #invalidate()} to invalidate the data source,
- * and prevent further loading.
- *
- * @param params Parameters for the load, including the key for the new page, and requested load
- * size.
- * @param callback Callback that receives loaded data.
- */
- public abstract void loadAfter(@NonNull LoadParamsLoading Pages
- * PagedList queries data from its DataSource in response to loading hints. {@link PagedListAdapter}
- * calls {@link PagedList#loadAround(int)} to load content as the user scrolls in a RecyclerView.
- * Updating Paged Data
- * A PagedList / DataSource pair are a snapshot of the data set. A new pair of
- * PagedList / DataSource must be created if an update occurs, such as a reorder, insert, delete, or
- * content update occurs. A DataSource must detect that it cannot continue loading its
- * snapshot (for instance, when Database query notices a table being invalidated), and call
- * {@link #invalidate()}. Then a new PagedList / DataSource pair would be created to load data from
- * the new state of the Database query.
- * Implementing a DataSource
- * To implement, extend one of the subclasses: {@link PageKeyedDataSource},
- * {@link ItemKeyedDataSource}, or {@link PositionalDataSource}.
- *
- * {@literal @}Dao
- * interface UserDao {
- * {@literal @}Query("SELECT * FROM user ORDER BY lastName ASC")
- * public abstract DataSource.Factory<Integer, User> usersByLastName();
- * }
- *
- * In the above sample, {@code Integer} is used because it is the {@code Key} type of
- * PositionalDataSource. Currently, Room uses the {@code LIMIT}/{@code OFFSET} SQL keywords to
- * page a large query with a PositionalDataSource.
- *
- * @param , List
, List
, List
, List> function, List source) {
- List dest = function.apply(source);
- if (dest.size() != source.size()) {
- throw new IllegalStateException("Invalid Function " + function
- + " changed return size. This is not supported.");
- }
- return dest;
- }
-
- // Since we currently rely on implementation details of two implementations,
- // prevent external subclassing, except through exposed subclasses
- DataSource() {
- }
-
- /**
- * Applies the given function to each value emitted by the DataSource.
- *
, List
, List
- * LivePagedListBuilder(dataSourceFactory,
- * new PagedList.Config.Builder().setPageSize(pageSize).build())
- *
- *
- * @param dataSourceFactory DataSource.Factory providing DataSource generations.
- * @param pageSize Size of pages to load.
- */
- public LivePagedListBuilder(@NonNull DataSource.Factory, List