Подтвердить что ты не робот

Фрагменты ViewPager исчезают при изменении поворота экрана

Я работаю над андроидным приложением, которое содержит ViewPager с Fragment s, например:

MainActivity (MainActivityFragment (screenSlideViewPager (Fragment s))), что означает:

Activity содержит Fragment содержит ViewPager содержит Fragment s

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

какие-либо идеи для решения этой проблемы?

РЕДАКТИРОВАТЬ 1

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getSupportFragmentManager().findFragmentByTag(TAG) == null) {
        final FragmentTransaction ft = getSupportFragmentManager()
                .beginTransaction();
        ft.add(android.R.id.content, new MainActivityFragment(), TAG);
        ft.commit();
    }
}

MainActivityFragment.java:

public class MainActivityFragment extends Fragment {
    private ViewPager mPager = null;
    private PagerAdapter mPageAdapter = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View reVal = inflater.inflate(R.layout.activity_main, container, false);
        mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
        mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());
        mPager.setAdapter(mPageAdapter);
        return reVal;
    }

    private MainGridViewFragment mainGridFragment;
    private AlphabetGridViewFragment alphabetGridFragment;

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public android.app.Fragment getItem(int position) {
            switch (position) {
                case 1:
                    mainGridFragment = new MainGridViewFragment();
                    return mainGridFragment;
                case 0:
                    alphabetGridFragment = new AlphabetGridViewFragment();
                    return alphabetGridFragment;
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 2;
        }
    }
}

РЕДАКТИРОВАТЬ 2 The Activity After Screen Rotation

Очевидно, загружаются MainActivity и MainActivityFragment, а доказательство - это ActionBar, обратите внимание также, что загружается ViewPager, потому что вы все еще можете перемещаться между страницами (синий свет означает, что пейджер достиг последней страницы), но вы не можете видеть его содержимое.

4b9b3361

Ответ 1

Похоже, ваша основная деятельность заключается в использовании getSupportFragmentManager(), в то время как ваш фрагмент использует getFragmentManager().

Не уверен, что это достойно ответа, но мой рейтинг слишком низок, чтобы ответить любым другим способом.:)

Изменить: я считаю, вам также может потребоваться расширить FragmentActivity с помощью библиотеки поддержки.

Смотрите: fooobar.com/questions/45509/...

Изменить 2:

public class MainActivityFragment extends FragmentActivity {
    private ViewPager mPager = null;
    private PagerAdapter mPageAdapter = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View reVal = inflater.inflate(R.layout.activity_main, container, false);
        mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
        mPageAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
        mPager.setAdapter(mPageAdapter);
        return reVal;
    }

    private MainGridViewFragment mainGridFragment;
    private AlphabetGridViewFragment alphabetGridFragment;

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 1:
                    mainGridFragment = new MainGridViewFragment();
                    return (Fragment)mainGridFragment;
                case 0:
                    alphabetGridFragment = new AlphabetGridViewFragment();
                    return (Fragment)alphabetGridFragment;
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 2;
        }
    }
}

Ответ 2

Я попробовал много решений, но добился успеха в любом. Наконец, я исправил, как показано ниже:

  • Используйте getActivity(). getSupportFragmentManager(), а не getChildFragmentManager()

  • Переопределите метод getItemId (int position) в классе ViewPagerAdapter, как показано ниже:

    @Override
    public long getItemId(int position) {
        return System.currentTimeMillis();
    }
    

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

Ответ 3

Для тех, у кого есть проблемы с этим, вы можете попробовать следующее:

private void InitializeUI(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.activity_exame2);
InitializeUI();
}

Я провел 2 дня вокруг этой проблемы, это единственное, что сработало для меня, помните, чтобы добавить android: configChanges = "screenSize | orientation" в вашу активность в манифесте

Ответ 4

Избегайте создания viewpager снова. Поместите код onCreateView в onCreate(). И сделайте ваш фрагмент использовать onRetainInstance (true). Следовательно, это не должно воссоздавать фрагмент и снова, потому что представление находится в onCreate(), оно не будет вызываться снова.

Проверьте в onCreateView(), существует ли представление, если да, то удалите его. Фрагменты:

//creates the view
private View createView(Bundle savedInstanceState) {
    View view = getActivity().getLayoutInflater().inflate(your_layout, null, false);

    //viewpager

    return view;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //retains fragment instance across Activity re-creation
    setRetainInstance(true);

    viewRoot = createView(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    if (viewRoot != null && viewRoot.getParent() != null) {
        ViewGroup parent = (ViewGroup) viewRoot.getParent();
        parent.removeView(viewRoot);

        Log.i("Test", "**************view.getParent(): " + viewRoot.getParent() + "    " + viewRoot);
    }

    return viewRoot;
}

Ответ 5

Вместо getFragmentManager() лучше использовать getChildFragmentManager(). Вы использовали

mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());

он должен был

mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getChildFragmentManager());

в вашем фрагменте

Ответ 6

У меня была такая же проблема. Это потрясающе сбивало с толку, но эта нить помогла мне, кроме того, что ответы на самом деле не объяснили, почему это работает.

Исправление этой проблемы заключается в использовании Fragment.getChildFragmentManager(). Что сбивает с толку API Android, Activity.getFragmentManager(), но если вы пытаетесь поддерживать старые устройства, вам нужно использовать Activity.getSupportFragmentManager(). Однако эта конкретная проблема заключается не в поддержке старых API.

Проблема в том, что у вас есть Activity, у которого есть фрагмент, которому принадлежит ViewPager, которому принадлежат несколько фрагментов. У вас есть фрагменты внутри фрагментов! Оригинальный дизайн Фрагментов на самом деле не справлялся с этим вариантом использования, а позже был обновлен для его обработки. Когда у вас есть фрагменты внутри фрагментов, вам нужно использовать:

Fragment.getChildFragmentManager()

Внутри Fragment у вас есть выбор Fragment.getFragmentManager(), который возвращает FragmentManager Activity vs Fragment.getChildFragmentManager(), который возвращает FragmentManager для этого Fragment, который должным образом просматривает Fragment в пределах Fragment.