Android 无休止滚动时分页库何时请求更多项目
Android Paging Library when to request more items when doing an endless scrolling
如何使用新的 android Paging Library 架构组件知道何时向服务器请求更多项目?例如,如果我想实现从服务器加载数据的无限滚动,我如何知道何时必须请求更多项目。
我使用下一个 class 来实现此功能:
package com.mlsdev.enjoymusic.data.repository;
import android.arch.paging.DataSource;
import android.arch.paging.TiledDataSource;
import android.arch.persistence.room.InvalidationTracker;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.mlsdev.enjoymusic.data.local.DeezerDatabase;
import com.mlsdev.enjoymusic.data.local.Table;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import retrofit2.Call;
import retrofit2.Response;
/**
* Created by stafievsky on 09.10.17.
*/
public abstract class PagedNetworkBoundResource<ResultType, RequestType> extends TiledDataSource<ResultType> {
private final InvalidationTracker.Observer mObserver;
private DeezerDatabase db;
public PagedNetworkBoundResource(DeezerDatabase db) {
this.db = db;
mObserver = new InvalidationTracker.Observer(Table.States.PLAY_STATE) {
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
this.db.getInvalidationTracker().addWeakObserver(mObserver);
}
@Override
public boolean isInvalid() {
db.getInvalidationTracker().refreshVersionsSync();
return super.isInvalid();
}
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<ResultType> loadRange(int startPosition, int count) {
if (startPosition == 0 && count == 20) {
clearDB();
}
fetchFromNetwork(startPosition, count);
return loadFromDb(startPosition, count);
}
public abstract void clearDB();
@WorkerThread
private void fetchFromNetwork(int startPosition, int count) {
if (createCall(startPosition, count) != null)
try {
Response<RequestType> response = createCall(startPosition, count).execute();
if (response.isSuccessful() && response.code() == 200) {
saveCallResult(response.body());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@WorkerThread
protected abstract void saveCallResult(@NonNull RequestType item);
@WorkerThread
protected abstract List<ResultType> loadFromDb(int startPosition, int count);
@WorkerThread
protected abstract Call<RequestType> createCall(int startPosition, int count);
}
以及此 class 的实现:
public LiveData<PagedList<ChartAlbumDao.Album>> getAlbums() {
return new LivePagedListProvider<Integer, ChartAlbumDao.Album>() {
@Override
protected DataSource<Integer, ChartAlbumDao.Album> createDataSource() {
return new PagedNetworkBoundResource<ChartAlbumDao.Album, ModelList<ChartAlbumEntity>>(db) {
@Override
public void clearDB() {
}
@Override
protected void saveCallResult(@NonNull ModelList<ChartAlbumEntity> item) {
if (item != null) {
chartAlbumDao.saveAlbums(item.getItems());
}
}
@NonNull
@Override
protected List<ChartAlbumDao.Album> loadFromDb(int startPosition, int count) {
return chartAlbumDao.loadAlbums(count, startPosition);
}
@NonNull
@Override
protected Call<ModelList<ChartAlbumEntity>> createCall(int startPosition, int count) {
return deezerService.getChartAlbums(startPosition, count);
}
};
}
}.create(0, new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPageSize(20)
.setInitialLoadSizeHint(20)
.build());
}
如何使用新的 android Paging Library 架构组件知道何时向服务器请求更多项目?例如,如果我想实现从服务器加载数据的无限滚动,我如何知道何时必须请求更多项目。
我使用下一个 class 来实现此功能:
package com.mlsdev.enjoymusic.data.repository;
import android.arch.paging.DataSource;
import android.arch.paging.TiledDataSource;
import android.arch.persistence.room.InvalidationTracker;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.util.Log;
import com.mlsdev.enjoymusic.data.local.DeezerDatabase;
import com.mlsdev.enjoymusic.data.local.Table;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import retrofit2.Call;
import retrofit2.Response;
/**
* Created by stafievsky on 09.10.17.
*/
public abstract class PagedNetworkBoundResource<ResultType, RequestType> extends TiledDataSource<ResultType> {
private final InvalidationTracker.Observer mObserver;
private DeezerDatabase db;
public PagedNetworkBoundResource(DeezerDatabase db) {
this.db = db;
mObserver = new InvalidationTracker.Observer(Table.States.PLAY_STATE) {
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
this.db.getInvalidationTracker().addWeakObserver(mObserver);
}
@Override
public boolean isInvalid() {
db.getInvalidationTracker().refreshVersionsSync();
return super.isInvalid();
}
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<ResultType> loadRange(int startPosition, int count) {
if (startPosition == 0 && count == 20) {
clearDB();
}
fetchFromNetwork(startPosition, count);
return loadFromDb(startPosition, count);
}
public abstract void clearDB();
@WorkerThread
private void fetchFromNetwork(int startPosition, int count) {
if (createCall(startPosition, count) != null)
try {
Response<RequestType> response = createCall(startPosition, count).execute();
if (response.isSuccessful() && response.code() == 200) {
saveCallResult(response.body());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@WorkerThread
protected abstract void saveCallResult(@NonNull RequestType item);
@WorkerThread
protected abstract List<ResultType> loadFromDb(int startPosition, int count);
@WorkerThread
protected abstract Call<RequestType> createCall(int startPosition, int count);
}
以及此 class 的实现:
public LiveData<PagedList<ChartAlbumDao.Album>> getAlbums() {
return new LivePagedListProvider<Integer, ChartAlbumDao.Album>() {
@Override
protected DataSource<Integer, ChartAlbumDao.Album> createDataSource() {
return new PagedNetworkBoundResource<ChartAlbumDao.Album, ModelList<ChartAlbumEntity>>(db) {
@Override
public void clearDB() {
}
@Override
protected void saveCallResult(@NonNull ModelList<ChartAlbumEntity> item) {
if (item != null) {
chartAlbumDao.saveAlbums(item.getItems());
}
}
@NonNull
@Override
protected List<ChartAlbumDao.Album> loadFromDb(int startPosition, int count) {
return chartAlbumDao.loadAlbums(count, startPosition);
}
@NonNull
@Override
protected Call<ModelList<ChartAlbumEntity>> createCall(int startPosition, int count) {
return deezerService.getChartAlbums(startPosition, count);
}
};
}
}.create(0, new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPageSize(20)
.setInitialLoadSizeHint(20)
.build());
}