Класс ViewModel, внутри которого мы загружаем список страниц, используя источник данных.
public class RecipeListViewModel extends ViewModel {
public LiveData<PagedList<RecipeListPojo>> mutableLiveData;
public void init(RecipeFrom recipeFrom, RecipeDao recipeDao) {
mutableLiveData = new
LivePagedListBuilder(recipeDao.getRecipeList(),10).build();
}
}
Это мой дао, в котором мы получаем данные в виде фабрики источников данных.
@Dao
public interface RecipeDao {
@Query("select * from recipe")
public DataSource.Factory<Integer, RecipeListPojo> getRecipeList();
}
Внутри моего RecipeListPojo я создал DiffCallBack.
public static DiffUtil.ItemCallback<RecipeListPojo> diffCallback=new
DiffUtil.ItemCallback<RecipeListPojo>() {
@Override
public boolean areItemsTheSame(RecipeListPojo oldItem, RecipeListPojo
newItem) {
return oldItem.getId()==newItem.getId();
}
@Override
public boolean areContentsTheSame(RecipeListPojo oldItem, RecipeListPojo
newItem) {
return oldItem.equals(newItem);
}
};
Внутри моей деятельности я получаю список страниц через наблюдателя и настраиваю свой адаптер.
arrayListObserver=new Observer<PagedList<RecipeListPojo>>() {
@Override
public void onChanged(@Nullable PagedList<RecipeListPojo> recipePojos) {
if (recipePojos!=null)
{
recipeAdapter.submitList(recipePojos);
recyclerView.setAdapter(recipeAdapter);
progressBar.setVisibility(GONE);
}
}
};
recipeFrom=new RecipeFrom.RecipeFromBuilder(fromActivity).build();
recipeDao=GlobalApplication.recipeRoomDatabase.getRecipeDao();
recipeListViewModel.init(recipeFrom,recipeDao);
recipeListViewModel.mutableLiveData.observe(this,arrayListObserver);
Так выглядит мой адаптер.
public class RecipeListAdapter extends
PagedListAdapter<RecipeListPojo,RecipeListAdapter.RecipeListHolder> {
private LayoutInflater inflater;
private Context context;
public RecipeListAdapter()
{
super(RecipeListPojo.diffCallback);
}
@Override
public RecipeListHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context=parent.getContext();
inflater=LayoutInflater.from(context);
View rootView = inflater.inflate(R.layout.one_item_recipe_list, null,
false);
return new RecipeListHolder(rootView);
}
@Override
public int getItemCount() {
return super.getItemCount();
}
}
Используемая библиотека
// Paging
implementation "android.arch.paging:runtime:1.0.0-rc1"
arrayListObserver наблюдает за mutableLiveData внутри действия, тогда только наблюдатель получает список страниц
вы видели developer.android.com/reference/android/arch/paging/…? он просто использует: viewModel.usersList.observe(this, pagedList -> adapter.submitList(pagedList));
- сделайте то же самое
На самом деле это то же самое.
что показывает Log.d(TAG, "size: " + recipePojos.size());
?
это показывает общее количество. элементов в моем списке, а не размер страниц (10), который я определил при создании страничного списка.
Я не могу найти этот адаптер.submitList (pagedList), потому что я использую // реализацию подкачки "android.arch.paging: runtime: 1.0.0-alpha4-1"
хорошо, сколько у вас строк? больше 30? (3 * 10)
У меня 1300 строк
хорошо, попробуйте Log.d(TAG, "list: " + recipePojos);
, обратите внимание, что вы увидите 30 "настоящих" предметов и 1270 null
- надеюсь, вы понимаете, что это значит
Спасибо @pskink да ты прав, у меня всего 30 объектов, остальные - нули
ты знаешь, откуда взялось 30?
Да, потому что я дал ограничение в 10 элементов, то есть 10 предыдущих, 10 текущих и 10 следующих.
Я бы посоветовал одному из вас добавить ответ на этот вопрос, поскольку теперь он решен.
Согласно моему исследованию, Я наконец обнаружил, что он возвращает список size = total no. элементов, но будет инициализирован только размер pagedList * 3, а остальные элементы будут нулевыми, и они будут обновляться при прокрутке recyclerView с помощью PagedListAdapter.
Хорошая находка .. !! Но остальные элементы не загружаются при прокрутке recyclerview. Какие-либо решения?
its showing the total no. of elements in my list rather than the pages size (10) that i have defined while creating the paged list
Используйте setEnablePlaceholders(false)
Предыдущий ответ:
После того, как я задумался об этом и прочитал комментарии и ответы, я обнаружил, что это связано с установленной вами конфигурацией. В частности, PageSize
.
Если вы установите его на 1 и прокрутите очень быстро, вы увидите заполнители, означающие, что все данные еще не загружены.
Из документация:
setPageSize
Defines the number of items loaded at once from the DataSource.
Should be several times the number of visible items onscreen.
Configuring your page size depends on how your data is being loaded and used. Smaller page sizes improve memory usage, latency, and avoid GC churn. Larger pages generally improve loading throughput, to a point (avoid loading more than 2MB from SQLite at once, since it incurs extra cost).
If you're loading data for very large, social-media style cards that take up most of a screen, and your database isn't a bottleneck, 10-20 may make sense. If you're displaying dozens of items in a tiled grid, which can present items during a scroll much more quickly, consider closer to 100.
P.S. Старайтесь не использовать setInitialLoadSizeHint
, если он вам действительно не нужен, потому что он будет работать в потоке пользовательского интерфейса, даже если вы указали fetchExecutor
в фоновом потоке.
где вы используете
mutableLiveData
? я это вижу только вRecipeListViewModel
, зачем тебеarrayListObserver
? почему вы не следуете образцу кода в документацииPagedListAdapter
?