Библиотека разбивки на страницы Android не перестанет загружать элементы в recyclerview

Я использую библиотеку разбивки на страницы Android... Она работает странным образом - элементы продолжают загружаться бесконечно, нет остановки, даже если больше нет данных для загрузки.

Например, у меня есть 2 элемента для загрузки, вместо того, чтобы загружать только 2 элемента и прекращать загрузку, он постоянно загружает 2 элемента... Вот gif того, с чем я столкнулся.

Загрузка изображения

Сначала вот мой репозиторий

CommentDataSource.java

Примечание. Когда я изменяю значение "PAGE_SIZE" на "1", кажется, что это работает, но вся цель разбиения на страницы не выполняется, поскольку ВСЕ элементы загружаются одновременно. . (Я тестировал больше предметов)

public class CommentDataSource extends PageKeyedDataSource<Long, Comment> {
public static int PAGE_SIZE = 10;
public static long FIRST_PAGE = 1;

 public CommentDataSource(){
  }

 @Override
 public void loadInitial(@NonNull final LoadInitialParams<Long> params, @NonNull final 
 LoadInitialCallback<Long, Comment> callback) {
 RestApi restApi = RetrofitApi.create();

 Call<CommentResponse> call = restApi.getComments(FIRST_PAGE);

 call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                callback.onResult(responseItems, null, FIRST_PAGE + 1);
            }
        }

   @Override
public void loadBefore(@NonNull final LoadParams<Long> params, @NonNull final LoadCallback<Long, Comment> callback) {
    RestApi restApi = RetrofitApi.create();

    Call<CommentResponse> call = restApi.getComments(params.key);

    call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                long key;
                if(params.key > 1){
                    key = params.key - 1;
                }
                else {
                    key = 0;
                }
                callback.onResult(responseItems, key);
            }
        }
    });

}

@Override
public void loadAfter(@NonNull final LoadParams<Long> params, @NonNull final LoadCallback<Long, Comment> callback) {

    RestApi restApi = RetrofitApi.create();

    Call<CommentResponse> call = restApi.getComments(params.key);

    call.enqueue(new Callback<CommentResponse>() {
        @Override
        public void onResponse(Call<CommentResponse> call, Response<CommentResponse> response) {
            CommentResponse commentResponse = response.body();
            if(commentResponse!=null){
                progress_bar.postValue(false);
                List<Comment> responseItems = commentResponse.getCommentResponses();
                callback.onResult(responseItems, params.key + 1);
            }
        }

    });
 }
}

Вот мой ViewModel

CommentViewModel.java

public class CommentViewModel extends ViewModel {
public CommentViewModel(){
    CommentDataFactory commentDataFactory = new CommentDataFactory();
    liveDataSource = commentDataFactory.commentLiveDataSource;

    progressBar = Transformations.switchMap(liveDataSource, CommentDataSource::getProgressBar);

    PagedList.Config config = new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setPageSize(CommentDataSource.PAGE_SIZE)
            .build();

    commentPagedList = new LivePagedListBuilder<>(commentDataFactory, config).build();
}


public LiveData<PagedList<Comment>> getCommentData(){
    return commentPagedList;
}

public void getRefreshedData(){
    getCommentData().getValue().getDataSource().invalidate();
   } 
 }

Вот мой код PHP для запроса к базе данных, который возвращает в формате JSON.

get_comments.php

<?php
  $limit = 10;

  //find out how many rows are in the table
  $sql = "SELECT count(*) FROM comments"; 
  $result = $conn->prepare($sql); 
  $result->execute();
  $total = $result->fetchColumn();
  $totalpages = ceil($total/$limit);

  if (isset($_GET['page']) && is_numeric($_GET['page'])) {
  $currentpage =  $_GET['page'];
  } else {
  // default page num
  $currentpage = 1;
  }

if ($currentpage > $totalpages) {
 // set current page to last page
 $currentpage = $totalpages;
 }

 // if current page is less than first page... 
if ($currentpage < 1) {
  $currentpage = 1; 
 } 

 //the offset of the list, based on current page 
 $offset = ($currentpage - 1) * $limit;


  $stmt = "SELECT * FROM comments ORDER by id DESC LIMIT $offset, $limit";
  $result = $conn->prepare($stmt); 
  $result->execute();

  $response = array(); 

  while ($row = $result->fetch()) {

  $temp['id']=$row['id'];
  $temp['image_id']=$row['image_id'];
  $temp['comment']=$row['comment'];
  $temp['comment_by']=$row['comment_by'];
  $temp['date_posted']=$row['date_posted'];

  array_push($response, $temp);

  $obj = (object) [ 
 'data' =>  $response
  ];

 }
echo json_encode($obj); 
?>

Это коды, которые, как мне кажется, необходимы... Я не добавлял адаптер и фабрику, но если нужно, я могу добавить другие коды... Кто-нибудь, пожалуйста, помогите, так как я занимаюсь этим уже несколько дней...

"


person Ibramazin    schedule 11.06.2020    source источник
comment
ваш источник данных уже является асинхронным, поэтому вы можете синхронизировать вызовы с помощью call.execute().   -  person Nikola Srdoč    schedule 11.06.2020
comment
Сколько страниц в вашей переменной $totalpages в php   -  person Vivek Singh    schedule 11.06.2020
comment
@NikolaSrdoč Я не понимаю??   -  person Ibramazin    schedule 11.06.2020
comment
@VivekSingh totalpages вернул 1 в php. Обычно общее количество страниц равно total/limit... В моем случае это 2/10 = 0,2.... Но поскольку текущая страница больше 0,2... $totalpages устанавливается в 1 из PHP-кода... .   -  person Ibramazin    schedule 11.06.2020
comment
@Ibramazin Методы загрузки в CommentDataSource выполняются в фоновом потоке. Это означает, что вы должны выполнять синхронную работу в этом потоке.   -  person Nikola Srdoč    schedule 11.06.2020
comment
@NikolaSrdoč Я думал, что синхронные запросы вызывают сбои приложения..??   -  person Ibramazin    schedule 11.06.2020
comment
ссылку можно найти здесь: ссылка Только для сети: для отображения данных из серверной части server, используйте синхронную версию Retrofit API для загрузки информации в собственный настраиваемый объект DataSource.   -  person Nikola Srdoč    schedule 11.06.2020
comment
Спасибо..@NikolaSrdoč Я переключился на синхронный вызов. Я заставил его работать благодаря Вивеку Сингху.... Но мне любопытно узнать, есть ли последствия для использования синхронного вызова модификации.... Потому что большинство учебных пособий, которые я вижу, используют асинхронный вызов..??   -  person Ibramazin    schedule 11.06.2020
comment
Вероятно, ребята из Google обновили свою документацию, в которой говорится, как использовать модернизацию в DataSource после того, как эти учебные пособия были написаны ... Никаких последствий, когда вы выполняете синхронизацию вызова модификации в фоновом потоке ... Если вы делаете это в потоке пользовательского интерфейса, приложение не будет компилироваться с исключением NetworkOnMainThreadException   -  person Nikola Srdoč    schedule 12.06.2020


Ответы (1)


Кажется, я понял, почему он загружается снова и снова, вот почему:

Сначала в loadInitial() вашего CommentDataSource вы передаете FIRST_PAGE + 1 в строке callback.onResult(responseItems, null, FIRST_PAGE + 1); из onReponse(), это означает, что в loadAfter() FIRST_PAGE + 1 передается как страница номер 2 в строке restApi.getComments(params.key), но страница номер 2 не существует в вашей базе данных, и вы установка того же номера страницы, если номер страницы больше 1 в вашем php

if ($currentpage > $totalpages) {
 // set current page to last page
 $currentpage = $totalpages;
 }

Итак, вы снова и снова звоните на страницу номер 1. В loadAfter() вы снова вызываете страницу 1, а затем снова и снова.

person Vivek Singh    schedule 11.06.2020
comment
Теперь это работает... Мне пришлось удалить эти строки кода if ($currentpage › $totalpages) { // установить текущую страницу как последнюю $currentpage = $totalpages; } СПАСИБО.... - person Ibramazin; 11.06.2020