Фрагмент в ViewPager с помощью FragmentPagerAdapter пуст при втором просмотре

у меня есть интерфейс фрагментов с вкладками внизу, которые открывают разные фрагменты в главном представлении.

у меня есть один конкретный фрагмент, который является списком элементов. Если пользователь выбирает один из элементов в этом списке, открывается другой фрагмент, содержащий viewpager, который прокручивается по горизонтали между всеми элементами в списке в предыдущем фрагменте. Это отлично работает.

viewpager использует FragmentPagerAdapter для отображения предметы.

проблема возникает, когда пользователь выбирает элемент в списке, рассматривает его, затем нажимает кнопку на панели вкладок, чтобы вернуться к списку, затем выбирает другой элемент. При втором выборе элемента вместо viewpager появляется пустой экран. Я не получаю ошибок в моем LogCat, когда это происходит.

Почему viewpager появляется только в первый раз?

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);
    }
}

11 ответов


у меня была та же проблема. Изменение родительского класса моего PageAdapter из android.support.v4.app.FragmentPagerAdapter до android.support.v4.app.FragmentStatePagerAdapter решить мою ViewPager показать вопрос на "второй раз"!


мне удалось решить эту проблему, заменив getFragmentManager() с getChildFragmentManager() в Родительском фрагменте. Этот родительский фрагмент создавал экземпляр android.поддержка.В4.приложение.FragmentPagerAdapter для того, чтобы содержать подкачки (скользящие) фрагменты, который требует менеджера фрагментов в конструкторе. В этот конструктор я передал возвращаемое значение getChildFragmentManager().

ссылка хакбода была ключевой (https://developer.android.com/about/versions/android-4.2.html#NestedFragments), который был найден в этом посте фрагменты фрагменты


для меня я должен был назвать это на моем viewpager:

myViewPager.setSaveFromParentEnabled(false);

У меня была проблема, когда viewpager не обновлялся, и все, что я видел, был пустой белый экран, где должны быть фрагменты. Я проходил в getChildFragmentManager, но это не помогло.


в моем конкретном случае, когда я использовал CoordinatorLayout с AppBarLayout и ViewPager, что решило это для меня было удаление android: fitsSystemWindows= "true" из моих свойств xml AppBarLayout.

Не спрашивайте меня, почему. Я знаю, что это звучит немного смешно и, как будто это не должно иметь корреляции, но это была единственная строка, которая вызывала проблемы, поскольку я уже использовал getChildFragmentManager() в моем адаптере. Я потратил целый день на отладку моего кода, чтобы найти это, поэтому я надеюсь, что это сэкономит кому-то еще некоторое время.


у меня была та же проблема, для которой я изменил адаптер с FragmentPagerAdapter до FragmentStatePagerAdapter и getFragmentManager() в Родительском фрагмент getChildFragmentManager()

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


мы обошли это, повторно реализовав элементы пейджера представления как стандартные представления, а не фрагменты и соответственно изменив адаптер.


Это поможет вам.

    viewPager.setOffscreenPageLimit(position);

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

@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);
    initViewPagerAdapter();
    return mView;
}
private void initViewPagerAdapter(){
    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();
}

@Override
public void onResume(){
    super.onResume();
    initViewPagerAdapter();
}

У меня было то же самое, во второй раз, когда я вызываю адаптер пейджера, дочернее представление возвращает исключение NullPointerException. И изменение адаптера в FragmentStatePagerAdapter также решит мою проблему.


Я получал эту же проблему на Xamarin Android с пустым экраном во второй раз.. Установка следующего исправила это для меня.

viewPager.SaveFromParentEnabled = false;

попробуйте поставить setOffscreenPageLimit (int limit) on родитель ViewPager.

mViewPager.setOffscreenPageLimit(totalPages-1);

это сработало для меня как шарм.

в моем случае у меня был фрагмент внутри TabLayout С ViewPager.

и еще один ViewPager внутри этого фрагмента. В первый раз все работает нормально, но когда я меняю вкладку и возвращаюсь назад, часть моего фрагмента пропала.