Фрагменты 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
, потому что вы все еще можете перемещаться между страницами (синий свет означает, что пейджер достиг последней страницы), но вы не можете видеть его содержимое.
Ответы
Ответ 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
.