新的分页库的所有示例都使用了Room库,Room为我们创建了一个数据源。在我自己的情况下,我需要创建自定义数据源。
这是我的视图模型类中应该返回实时数据的方法。我的liveata总是返回null。
LiveData<PagedList<ApiResult>> getData(){
LivePagedListProvider<Integer,ApiResult> p = new LivePagedListProvider<Integer, ApiResult>() {
@Override
protected DataSource<Integer, ApiResult> createDataSource() {
return new DataClass();
}
};
listLiveData = p.create(0,new PagedList.Config.Builder()
.setPageSize(5) //number of items loaded at once
.setPrefetchDistance(0)// the distance to the end of already loaded list before new data is loaded
.build());
return listLiveData;
}
这是Data类
public class DataClass extends TiledDataSource<ApiResult> {
private List<ApiResult> result = new ArrayList<>();
@Override
public int countItems() {
return result.size();
}
@Override
public List<ApiResult> loadRange(int startPosition, int count) {
Call<String> call = NetworkModule.providesWebService().makeRequest();
call.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
Log.i(DataClass.this.getClass().getSimpleName() + " - onResponse", String.valueOf(response));
result = parseJson(response.body());
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
Log.i(DataClass.this.getClass().getSimpleName() + " - onFailure", t.getMessage());
}
});
return result;
}
}
答案 0 :(得分:7)
我认为这有助于:
1. countItems()应该返回DataSource.COUNT_UNDEFINED
2. loadRange(int startPosition,int count):您可以直接执行查询。
3.现在你可以删除结果全局变量
此外,关闭占位符:
listLiveData = p.create(0,new PagedList.Config.Builder()
.setPageSize(5) //number of items loaded at once
.setPrefetchDistance(10) //Must be >0 since placeholders are off
.setEnablePlaceholders(false)
.build());
以下是数据类的更新代码:
public class DataClass extends TiledDataSource<ApiResult> {
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<ApiResult> loadRange(int startPosition, int count) {
Call<String> call = NetworkModule.providesWebService().makeRequest();
Response<String> response = call.execute();
return parseJson(response.body());
}
您可以在此处查看示例项目: https://github.com/brainail/.samples/tree/master/ArchPagingLibraryWithNetwork
答案 1 :(得分:2)
您可以创建一个自定义数据源,通常我们构建了后端API以获取以pagenumber作为参数以返回指定页面的数据。
在这种情况下,您可以使用PageKeyedDataSource。这是使用StackOverflow API的PageKeyedDataSource示例代码。以下代码使用Retrofit从StackOverflow API获取数据。
public class ItemDataSource extends PageKeyedDataSource<Integer, Item> {
//the size of a page that we want
public static final int PAGE_SIZE = 50;
//we will start from the first page which is 1
private static final int FIRST_PAGE = 1;
//we need to fetch from stackoverflow
private static final String SITE_NAME = "stackoverflow";
//this will be called once to load the initial data
@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull final LoadInitialCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(FIRST_PAGE, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
if (response.body() != null) {
callback.onResult(response.body().items, null, FIRST_PAGE + 1);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
//this will load the previous page
@Override
public void loadBefore(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
//if the current page is greater than one
//we are decrementing the page number
//else there is no previous page
Integer adjacentKey = (params.key > 1) ? params.key - 1 : null;
if (response.body() != null) {
//passing the loaded data
//and the previous page key
callback.onResult(response.body().items, adjacentKey);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
//this will load the next page
@Override
public void loadAfter(@NonNull final LoadParams<Integer> params, @NonNull final LoadCallback<Integer, Item> callback) {
RetrofitClient.getInstance()
.getApi()
.getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback<StackApiResponse>() {
@Override
public void onResponse(Call<StackApiResponse> call, Response<StackApiResponse> response) {
if (response.body() != null) {
//if the response has next page
//incrementing the next page number
Integer key = response.body().has_more ? params.key + 1 : null;
//passing the loaded data and next page value
callback.onResult(response.body().items, key);
}
}
@Override
public void onFailure(Call<StackApiResponse> call, Throwable t) {
}
});
}
}
在这里您可以看到我们通过进行Retrofit调用获得了结果,然后将结果推送给了回调。
有关详细的逐步说明,请遍历此Android Paging Library Tutorial。