0

Я показываю набор элементов в RecyclerView. Данные загружаются с сервера, и одна группа элементов загружается за каждый раз. Однако иногда только одна группа данных не может заполнить экран, поэтому я хочу сделать RecyclerView способным обнаружить эту проблему и начать загрузку следующей группы данных до тех пор, пока экран не будет заполнен.Как заставить ListView или RecyclerView продолжать загружать больше данных автоматически до тех пор, пока не будет заполнен экран.

Например, если данных на странице 1 недостаточно, загрузите данные на страницу 2. Если все еще нет, загрузите данные на странице 3 и т. Д.

Часть обнаружения не сложно, так как я могу получить параметры ниже:

int visibleItemCount = mLayoutManager.getChildCount(); 
    int totalItemCount = mLayoutManager.getItemCount(); 
    int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition(); 

Но проблема возникает с notifyDataSetChanged(). Например, ниже мой код установочных данных:

public void setData(List data){ 
    updataData(data); 
    mAdapter.notifyDataSetChanged(); 
    if(ifScreenNotFilled()){ 
     loadNextGroupData(); // it calls 'setData()' recursively 
    } 
} 

Когда loadNextGroupData() называется, то setData вызывается рекурсивно. И получается, что размер списка данных продолжает расширяться, а visibleItemCount всегда равен нулю, и на экране ничего не появляется.

Если я удалю часть рекурсии кода, первая группа данных будет загружена на экран. Мне очень любопытно механизм notifyDataSetChanged().

Итак, есть ли решение для получения RecyclerView, которое автоматически обновляется, когда оно не заполняет экран?

ответ

0

Я нашел причину, по которой notifyDataSetChanged() не работает. Это связано с тем, что рекурсивный вызов метода setData() делает его никогда не возвращается. Таким образом, notifyDataSetChanged() не может быть выполнен потоком пользовательского интерфейса.

Решение использует Handler для размещения рекурсивной части в очереди сообщений в потоке пользовательского интерфейса.

mHandler = new Handler(Looper.getMainLooper()); 
public void setData(List data){ 
    updataData(data); 
    mAdapter.notifyDataSetChanged(); 
    if(ifScreenNotFilled()){ 
     mHandler.post(new Runnable(){ 
      @override 
      public void run(){ 
       loadNextGroupData(); 
      } 
     } 
    } 
} 

Для тех, кто может видеть этот вопрос позже, бетон implementaion коды выше, можно найти в моем репо: https://github.com/SphiaTower/AutoPagerRecyclerManager.

Пожалуйста, проверьте метод setData()https://github.com/SphiaTower/AutoPagerRecyclerManager/blob/master/lib/src/main/java/tower/sphia/auto_pager_recycler/lib/AutoPagerRecyclerViewManager.java в

0

Попробуйте использовать getHeight() на вашем mRecyclerView и получить его высоту и сравнить его с высотой отображения.

int height = getWindow().getWindowManager().getDefaultDisplay().getHeight() 
+0

Основная проблема заключается в том, чтобы загрузить данные рекурсивно. Каждый раз, когда загружается группа данных, необходимо проверить, заполнен ли экран. Если нет, необходимо загрузить новую группу данных, и проверка будет выполнена снова. – ProtossShuttle

+0

да, чтобы вы могли получить высоту отображения в onCreate (чтобы убедиться, что это изменено при вращении устройства), а затем сравните его с вашим recyclerView при каждом загрузке данных. Если экран заполнен после последней загрузки, ничего не делайте, если нет - загрузите больше. –

+0

Спасибо, но на самом деле данные загрузки и код проверки выполняются рекурсивно. Я знаю, что ожидается, что просмотр на экране будет обновляться каждый раз, когда данные обновляются, но это не так. 'NotifyDataSetChanged()' не работает, потому что метод никогда не возвращается. Поэтому каждый раз, когда я проверяю высоту recyclerview, результат всегда будет 0. – ProtossShuttle