Пейджинговая библиотека без помещения

Все примеры новой библиотеки подкачки были связаны с библиотекой Room, и Room создает для нас источник данных. В моем случае мне нужно создать собственный источник данных.

Вот метод в моем классе модели представления, который должен возвращать данные в реальном времени. Мои живые данные всегда возвращают значение 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;
    }

}

person Idee    schedule 07.10.2017    source источник


Ответы (2)


Я думаю, это может помочь:
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

person Ritesh Chandnani    schedule 10.10.2017
comment
Liveata по-прежнему пуста - person Idee; 11.10.2017
comment
Я считаю, что мы должны сохранить prefetchDistance ›0, потому что только что я попытался установить расстояние предварительной выборки на 0 и отключил заполнители, и это вызвало ошибку: Причина: java.lang.IllegalArgumentException: заполнители и предварительная выборка - единственные способы запуска загрузка дополнительных данных в PagedList, поэтому либо должны быть включены заполнители, либо расстояние предварительной выборки должно быть ›0. - person Ritesh Chandnani; 12.10.2017
comment
Проверьте мое репо github.com/KingIdee/pagination-with-network-call Вы можете сделать запрос на перенос - person Idee; 13.10.2017
comment
Обязательно посмотрю - person Ritesh Chandnani; 13.10.2017
comment
@Idee Я отправил запрос на перенос, посмотрите, он работает как шарм! - person Ritesh Chandnani; 16.10.2017

Вы можете создать собственный источник данных, обычно мы создали серверный API для извлечения данных, который принимает номер страницы в качестве параметра для возврата указанной страницы.

В этой ситуации вы можете использовать PageKeyedDataSource. Вот пример кода PageKeyedDataSource с использованием API StackOverflow. В приведенном ниже коде используется Retrofit для получения данных из API StackOverflow.

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 < / strong>.

person Kashfa Khan    schedule 09.08.2018