Paging Library without Room

前端 未结 2 1919
星月不相逢
星月不相逢 2021-02-20 03:11

All examples of the new paging library have been with Room library and Room creates a Data Source for us. In my own case, I need to create my custom data source.

Here is

相关标签:
2条回答
  • 2021-02-20 03:23

    I think this can help:
    1. countItems() should return DataSource.COUNT_UNDEFINED
    2. loadRange(int startPosition, int count): You can directly execute your query.
    3. So now you can delete result global variable

    Also, turnoff placeholders:

    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());
    

    Here is the updated code for Data Class:

    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());
    }
    

    You can check an example project here: https://github.com/brainail/.samples/tree/master/ArchPagingLibraryWithNetwork

    0 讨论(0)
  • 2021-02-20 03:35

    You can create a Custom Data Source, usually we built backend API to fetch data that takes pagenumber as a parameter to return the specified page.

    For this situation you can use PageKeyedDataSource. Here is a sample code of PageKeyedDataSource using the StackOverflow API. The below code is using Retrofit to get the data from the 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) {
    
                        }
                    });
        }
    }
    

    Here you can see we are getting the result by making a Retrofit call and then we are pushing the result to callback.

    For a detailed, step by step explanation go through this Android Paging Library Tutorial.

    0 讨论(0)
提交回复
热议问题