ViewPager + FragmentStatePagerAdapter +方向更改

我有一点问题:我有一个页面的ViewPager,我使用FragmentStatePagerAdapter来处理数据。 在肖像中,我有例如ViewPager的20页和在景观中,我只有10页的ViewPager。 所以在一个方向改变我创build一个新的适配器与不同的数据。

这里有一个小的解释,为什么:我在纵向上显示一个图像,在横向上显示两个图像,但总是在数量上。 如果我有10张照片要显示,我有10张纵向照片和5张横向照片(总是两张)。

但现在我有一个奇怪的错误:当我在索引5的景观,并转动设备,ViewPager的当前页面设置为10.如果我把它又回来了,我在页面5上。如果我现在将页面刷到页面10适配器的方法getItem永远不会被调用,并且ViewPage向我显示一个肖像图片,而不是两个风景。 这怎么可能发生? 在适配器或ViewPager中是否有caching? 在Activity的onCreate中,一切都是新创build的,适配器以及ViewPager的数据(只是带有path的string)。 那么任何想法如何解决这个真正可怕的“function”?

这里是一些代码:

的onCreate:

mViewPagerAdapter = new ReaderPageViewAdapter(getSupportFragmentManager(), getBaseContext(), mCurrentDocument.mPages, getResources() .getConfiguration().orientation); mPageReader = (ReaderViewPager) findViewById(R.id.pager); mPageReader.setAdapter(mViewPagerAdapter); 

适配器getItem:

  public Fragment getItem(final int index) { final PageInfo pageInfo = mPages.get(index); final PageFragment pageFragment = (PageFragment) PageFragment .instantiate(mContext, pageInfo.mClss.getName(), pageInfo.mArgs); return pageFragment; } 

如果你需要更多的东西,请告诉我。 谢谢

Solutions Collecting From Web of "ViewPager + FragmentStatePagerAdapter +方向更改"

您可以重写FragmentActivity onSaveInstanceState(),而不是调用方法中的super.onSaveInstanceState()。

 @Override protected void onSaveInstanceState(final Bundle outState) { // super.onSaveInstanceState(outState); } 

不要使用 mViewPager.setSaveEnabled(false);

它结束了一个很大的memory leaks。 在每次方向改变之后,它将碎片放入一个FragmentManager数组中,并且永远不会清理它。 因此多次改变方向后,内存使用量会超过100MB。 使用onSaveInstanceState方法是我想的一个更​​好的方法。

我也发生了这个问题,我find了原因。

通过屏幕旋转, FragmentManager将保留您的所有活动托pipe片段,它不会删除片段如果使用FragmentStatePagerAdapter ,则可以使用FragmentManager.getFragments()来检查片段的数量。

例如:活动有4个片段,在4次方向改变之后,列表FragmentManager.getFragments()大小将是20

我发现一些解决scheme:

  1. 不要调用你的Activity的super.onSaveInstanceState() ,但这似乎不是一个好的解决scheme,Fragments不能保存状态和恢复。

  2. 使用FragmentPagerAdapter而不是FragmentStatePagerAdapter 。 但是在方向改变之后, ViewPager托pipe的片段被空白(其他人是否也有同样的问题?)。 但是我可以删除Activity.onCreate中的所有片段来修复它。 喜欢这个:

     public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); List<Fragment> fragments = fm.getFragments(); if (fragments != null) { FragmentTransaction transaction = fm.beginTransaction(); for (Fragment fragment : fragments) { transaction.detach(fragment).remove(fragment); } transaction.commitNowAllowingStateLoss(); } ... 

    但是Fragment.onCreateView()调用了两次。

我仍然在寻找完美的解决scheme:D

编辑:
我终于解决了这个问题,这是因为我的ViewPager是在onStart之后添加的。 当运行到onStart时, FragmentManager将尝试恢复碎片状态。 我追溯到FragmentManager ,有这些代码:

COM /安卓/支持/支持片段/ 24.2.1 /支片段的24.2.1 – sources.jar!/android/support/v4/app/FragmentManager.java

检查高亮行, f.mContainerId实际上是我的ViewPager ID。 然后它会尝试添加片段视图到ViewPager,在我的情况下,ViewPager没有添加,所以它会被空白,但片段状态是ATTACHED 。 而在FragmentPagerAdapter.instantiateItem() ,如果添加了片段,则只是attach了片段,但片段已经附加了,所以它什么都不做:(

我将ViewPager添加到其固定的活动布局XML中。

快乐编码:D

只要你在viewPager.setonpagechangelistener中使用,并为需求代码应用你的应用程序,

http://developer.android.com/reference/android/support/v4/view/ViewPager.html