У меня есть интерфейс фрагментов с вкладками внизу, которые открывают разные фрагменты в основном представлении.
У меня есть один конкретный фрагмент, который представляет собой список предметов. Если пользователь выбирает один из элементов в этом списке, открывается другой фрагмент, который содержит окно просмотра, которое прокручивается по горизонтали между всеми элементами в списке в предыдущем фрагменте. Это прекрасно работает.
Viewpager использует FragmentPagerAdapter для отображения элементов.
Проблема возникает, когда пользователь выбирает элемент в списке, просматривает его, затем нажимает кнопку на панели вкладок, чтобы вернуться к списку, а затем выбирает другой элемент. При втором выборе элемента вместо окна просмотра появляется пустой экран. Когда это происходит, я не получаю ошибок в моем LogCat.
Почему окно просмотра появляется только в первый раз?
FragmentPagerAdapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
Cursor mCursor;
public ViewPagerAdapter(FragmentManager fm, Cursor c) {
super(fm);
mCursor = c;
}
public void changeCursor(Cursor c) {
mCursor = c;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
if (mCursor == null) return 0;
else return mCursor.getCount();
}
@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
return TeamCardFragment.newInstance(mCursor, position);
}
}
PagerFragment:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
View mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
new setAdapterTask().execute();
return mView;
}
private class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mCursorPosition);
}
}
FragmentPagerAdapter
иFragmentStatePagerAdapter
заключается в том, что первый больше подходит для нескольких страниц, он сохраняет все фрагменты в памяти, обеспечивая лучшую производительность при переключении страниц, в то время как последний больше подходит для многих страниц, он уничтожает фрагменты, сохраняя только их состояние, это более эффективно с точки зрения памяти, но немного медленнее при переключении страниц.Мне удалось решить эту проблему путем замены
getFragmentManager()
сgetChildFragmentManager()
в родительском фрагменте. Этот родительский фрагмент создавал экземпляр android.support.v4.app.FragmentPagerAdapter , чтобы содержать перелистываемые (скользящие) фрагменты, для чего требуется диспетчер фрагментов в конструкторе. Этому конструктору я передал возвращаемое значениеgetChildFragmentManager()
.Ссылка hackbod была ключевой ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ), которая была найдена в этом посте Фрагменты внутри фрагментов
источник
FragmentStatePagerAdapter
решает поставленный здесь вопрос. вместе сFragmentStatePagerAdapter
родительским фрагментомYourAdapter adapter = new YourAdapter (getChildFragmentManager());
должен быть добавлендля меня я должен был вызвать это в моем окне просмотра:
У меня была проблема, когда окно просмотра не обновлялось, и все, что я видел, было пустым белым экраном, на котором должны быть фрагменты. Я проходил через getChildFragmentManager, но это не помогло.
источник
В моем конкретном случае, когда я использовал CoordinatorLayout с AppBarLayout и ViewPager, для меня это решило удаление android: fitsSystemWindows = "true" из моих свойств AppBarLayout xml .
Не спрашивайте меня почему. Я знаю, что это звучит немного нелепо и похоже, что у него не должно быть корреляции, но именно эта единственная строка вызывала проблемы, поскольку я уже использовал getChildFragmentManager () в своем адаптере. Я потратил целый день на отладку своего кода, чтобы найти это, так что надеюсь, что это сэкономит время кому-то еще.
источник
У меня была такая же проблема, из-за которой я изменил адаптер с
FragmentPagerAdapter
наFragmentStatePagerAdapter
иgetFragmentManager()
в родительском фрагменте наgetChildFragmentManager()
Причина в том, что это
FragmentStatePagerAdapter
полезно для хранения большого количества страниц, а память, связанная с каждой посещенной страницей, меньше, поскольку она сохраняет только сохраненное состояние фрагмента, в то время как страница не отображается. Это снижает накладные расходы при переключении между фрагментами.источник
Попробуйте поставить
setOffscreenPageLimit (int limit)
на родительский ViewPager.Это сработало для меня как шарм.
В моем случае внутри был фрагмент
TabLayout
сViewPager.
И еще один
ViewPager
внутри этого фрагмента. В первый раз все работает нормально, но когда я меняю вкладку и возвращаюсь обратно, некоторые из моих фрагментов становятся пустыми.источник
Это вам поможет.
источник
Мы обошли это, повторно реализовав элементы пейджера представлений как стандартные представления, а не фрагменты, и соответствующим образом изменив адаптер.
источник
У меня была такая же проблема на Xamarin Android с пустым экраном во второй раз ... Установка следующего исправила это для меня.
источник
Вы также можете инициализировать адаптер на случай возникновения этой ошибки, когда ваше приложение свернуто и позже вызвано.
источник
У меня было то же самое, во второй раз, когда я вызываю адаптер пейджера, дочернее представление возвращает исключение NullPointerException. И изменение адаптера в FragmentStatePagerAdapter тоже решает мою проблему.
источник
Изменение
FragmentPagerAdapter
вFragmentStatePagerAdapter
использованииgetChildFragmentManager()
вместоgetFragmentManager()
getChildFragmentManager()
- потому что, согласно документации, он вернет частный FragmentManager для размещения и управления фрагментами внутри этого фрагмента. Тем временемgetFragmentManager()
вернет FragmentManager для взаимодействия с фрагментами, связанными с этим действием.источник
class ViewPagerAdapter расширяет FragmentStatePagerAdapter, эта работа для меня попробуйте это
источник