Я использую CursorLoader для загрузки данных из базы данных внутри моего фрагмента, который имеет RecyclerView .Этот фрагмент используется внутри ViewPager. ViewPager содержится внутри ContainerFragment, который, в свою очередь, находится внутри Activity.
ContainerFragment инициализирует первые 4 загрузчика из 10, требуемых в onActivityCreated()
.Из журнала я вижу, что загрузчик (и) фактически создается.Однако onLoadFinished
не вызывается ни для одного из загрузчиков.
Теперь поворот происходит, когда я пролистываю ViewPager к третьему фрагменту.Теперь я вижу, как вызывается третий загрузчик onLoadFinished
.Теперь это, вероятно, вызывается не из фрагмента, а из метода getItem()
PagerAdapter, который помимо создания фрагментов также инициализирует загрузчики с их идентификаторами, если они еще не были.
Из всех других вопросов на StackOverflow о том, что onLoadFinished не вызывается , я пробовал следующие решения, которые не работают для меня:
- Использование
forceLoad()
this.getListView().refreshDrawableState();
-> Не пытался, и не понимаю, почему это должно работать.Более того, я использую RecyclerView. - «Импорт правильного класса» -> Я использую AndroidX, и более того, иногда загружается загрузчик.Если это был неправильный класс, он не сработал бы в любое время, верно?
- «Фрагмент должен использовать
SupportLoaderManager
» -> попытался заменить фрагмент на getActivity().getSupportLoaderManager
.Для фрагмента я думаю, что это просто getLoaderManager
.Это уже работало иногда только с getLoaderManager
.(Различий не наблюдается)
#onActivityCreated
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
startLoaders();
}
startLoaders()
private void startLoaders() {
while(loaderSeqIndex < CATEGORIES.size() && loaderSeqIndex < 4) {
Bundle bundle = new Bundle();
bundle.putString("category", CATEGORIES.get(loaderSeqIndex));
getLoaderManager().initLoader(loaderSeqIndex++, bundle, this);
}
}
LoaderCallbacks
@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
Timber.i("Loader created onCreateLoader called");
CursorLoader loader = ArticleLoader.newCategorizedArticlesInstance(getContext(), args.getString("category"));
loader.registerListener(id, new Loader.OnLoadCompleteListener<Cursor>() {
@Override
public void onLoadComplete(Loader<Cursor> loader, Cursor data) {
int position = loader.getId();
cursorHashMap.put(CATEGORIES.get(position), data);
Timber.i("mPager.getCurrentItem(): " + mPager.getCurrentItem() + " position: " + position);
if (position == mPager.getCurrentItem()) {
ArticleListViewModel model = ViewModelProviders.of(ArticleListContainerFragment.this).get(ArticleListViewModel.class);
model.setCursor(data);
}
}
});
return loader;
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
int position = loader.getId();
cursorHashMap.put(CATEGORIES.get(position), data);
Timber.i("mPager.getCurrentItem(): " + mPager.getCurrentItem() + " position: " + position);
if(position == mPager.getCurrentItem()) {
ArticleListViewModel model = ViewModelProviders.of(this).get(ArticleListViewModel.class);
model.setCursor(data);
// mPagerAdapter.notifyDataSetChanged();
}
}
PagerAdapter's #getView
private class MyPagerAdapter extends FragmentStatePagerAdapter {
...
@Override
public Fragment getItem(int position) {
ArticleListFragment fragment = ArticleListFragment.newInstance();
Bundle bundle = new Bundle();
bundle.putString("category", CATEGORIES.get(position));
bundle.putInt("id",position);
fragment.setArguments(bundle);
// fragment.setCursor(cursorHashMap.get(CATEGORIES.get(position)));
return fragment;
}
...
}
Я ожидал, что древесина будет печататься по методу #onLoadFinished
, чтобы сделатьуверен, что его вызывают, чего не происходит.
Что-то странное происходит: cursorHashMap
, который я использую, get правильно заполнен, я открываю приложение секундувремя (когда обновление не происходит).И курсор заполняется без вызова #onLoadFinished
.