我有一个小问题:我有一个包含一些页面的ViewPager,并且我使用FragmentStatePagerAdapter来处理数据。例如,在纵向,我有20页用于ViewPager,而在横向,我只有10页用于ViewPager。因此,在方向更改时,我使用不同的数据创建了一个新的Adapter。
这里解释一下为什么:我在肖像中显示了一个图像,在风景中显示了两个图像,但总是在计数中。如果我有10张照片要展示,我有10张是纵向的,5张是风景的(总是两张)。
但现在我有了一个奇怪的bug:当我在横屏的索引5上翻转设备时,ViewPager的当前页面被设置为10。如果我再次翻回它,我就在第5页。如果我现在将ViewPage滑动到第10页,适配器的方法getItem永远不会被调用,ViewPage会显示一张纵向图片,而不是两张横向图片。这怎么会发生呢?适配器或ViewPager中是否有缓存?在活动的onCreate中,所有内容都是新创建的,包括适配器和ViewPager的数据(只是带有路径的字符串)。那么,你知道如何修复这个真正可怕的“功能”吗?
下面是一些代码:
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;
}如果你还需要什么,尽管告诉我。谢谢
发布于 2013-01-29 16:41:27
您可以覆盖FragmentActivity onSaveInstanceState(),而不调用该方法中的super.onSaveInstanceState()。
@Override
protected void onSaveInstanceState(final Bundle outState) {
// super.onSaveInstanceState(outState);
}请勿使用 mViewPager.setSaveEnabled(false);
它最终得到了一个很大的memoryLeak。每次更改方向后,它都会将片段放入一个FragmentManager数组中,并且永远不会清理它。因此,在多次更改方向后,内存使用量将超过100mb。我认为使用onSaveInstanceState方法是一种更好的方法。
发布于 2016-10-26 00:24:36
我也遇到了这个问题,我找到了原因。
当屏幕旋转时,FragmentManager将保留您所有的活动托管片段,如果使用FragmentStatePagerAdapter,它将不会删除片段,您可以使用FragmentManager.getFragments()检查片段的数量。
示例:该活动有4个片段,经过4次方向更改后,列表FragmentManager.getFragments()大小将为20!
我找到了一些解决方案:
super.onSaveInstanceState(),但这似乎不是一个好的解决方案,碎片无法保存状态和恢复。FragmentPagerAdapter而不是FragmentStatePagerAdapter。但是在方向改变后,ViewPager托管的片段被清除了(其他人也有同样的问题吗?)但我可以删除Activity.onCreate中的所有片段来修复它。如下所示:transaction.detach(fragment).remove(fragment);onCreate( savedInstanceState) { super.onCreate(savedInstanceState);FragmentManager fm = getSupportFragmentManager();List fragments = fm.getFragments();if (Fragment != null) { FragmentTransaction transaction = fm.beginTransaction();for ( fragment : fragments) { public } transaction.commitNowAllowingStateLoss();} ...
但是Fragment.onCreateView()打了两次电话。
我仍然在寻找完美的解决方案:D
编辑:
我终于解决了这个问题,因为我的ViewPager是在onStart之后添加的。当运行到onStart时,FragmentManager将尝试恢复片段状态。我追踪到了FragmentManager,有这些代码:
检查突出显示的行,f.mContainerId实际上是我的ViewPager id。然后它会尝试将片段视图添加到ViewPager,在我的例子中,ViewPager还没有被添加,所以它将被清空,但是片段状态是ATTACHED。在FragmentPagerAdapter.instantiateItem()中,如果添加了片断,它只会对片断执行attach操作,但是片断已经附加了,所以它什么也不做:(
我将ViewPager添加到活动布局可扩展标记语言,它是固定的。
快乐编码:D
发布于 2012-12-17 18:18:05
只要在viewPager.setonpagechangelistener中使用并实现所需代码即可应用您的应用程序,
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
https://stackoverflow.com/questions/13910826
复制相似问题