首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ViewPager + FragmentStatePagerAdapter +方向更改

ViewPager + FragmentStatePagerAdapter +方向更改
EN

Stack Overflow用户
提问于 2012-12-17 16:44:14
回答 3查看 18K关注 0票数 12

我有一个小问题:我有一个包含一些页面的ViewPager,并且我使用FragmentStatePagerAdapter来处理数据。例如,在纵向,我有20页用于ViewPager,而在横向,我只有10页用于ViewPager。因此,在方向更改时,我使用不同的数据创建了一个新的Adapter。

这里解释一下为什么:我在肖像中显示了一个图像,在风景中显示了两个图像,但总是在计数中。如果我有10张照片要展示,我有10张是纵向的,5张是风景的(总是两张)。

但现在我有了一个奇怪的bug:当我在横屏的索引5上翻转设备时,ViewPager的当前页面被设置为10。如果我再次翻回它,我就在第5页。如果我现在将ViewPage滑动到第10页,适配器的方法getItem永远不会被调用,ViewPage会显示一张纵向图片,而不是两张横向图片。这怎么会发生呢?适配器或ViewPager中是否有缓存?在活动的onCreate中,所有内容都是新创建的,包括适配器和ViewPager的数据(只是带有路径的字符串)。那么,你知道如何修复这个真正可怕的“功能”吗?

下面是一些代码:

onCreate:

代码语言:javascript
复制
    mViewPagerAdapter = new ReaderPageViewAdapter(getSupportFragmentManager(), getBaseContext(), mCurrentDocument.mPages, getResources()
                .getConfiguration().orientation);
    mPageReader = (ReaderViewPager) findViewById(R.id.pager);
    mPageReader.setAdapter(mViewPagerAdapter);

适配器getItem:

代码语言:javascript
复制
    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;
    }

如果你还需要什么,尽管告诉我。谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-29 16:41:27

您可以覆盖FragmentActivity onSaveInstanceState(),而不调用该方法中的super.onSaveInstanceState()。

代码语言:javascript
复制
@Override
protected void onSaveInstanceState(final Bundle outState) {
    // super.onSaveInstanceState(outState);
}

请勿使用 mViewPager.setSaveEnabled(false);

它最终得到了一个很大的memoryLeak。每次更改方向后,它都会将片段放入一个FragmentManager数组中,并且永远不会清理它。因此,在多次更改方向后,内存使用量将超过100mb。我认为使用onSaveInstanceState方法是一种更好的方法。

票数 42
EN

Stack Overflow用户

发布于 2016-10-26 00:24:36

我也遇到了这个问题,我找到了原因。

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

示例:该活动有4个片段,经过4次方向更改后,列表FragmentManager.getFragments()大小将为20

我找到了一些解决方案:

  1. 不调用活动的super.onSaveInstanceState(),但这似乎不是一个好的解决方案,碎片无法保存状态和恢复。
  2. 使用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,有这些代码:

com/android/support/support-fragment/24.2.1/support-fragment-24.2.1-sources.jar!/android/support/v4/app/FragmentManager.java

检查突出显示的行,f.mContainerId实际上是我的ViewPager id。然后它会尝试将片段视图添加到ViewPager,在我的例子中,ViewPager还没有被添加,所以它将被清空,但是片段状态是ATTACHED。在FragmentPagerAdapter.instantiateItem()中,如果添加了片断,它只会对片断执行attach操作,但是片断已经附加了,所以它什么也不做:(

我将ViewPager添加到活动布局可扩展标记语言,它是固定的。

快乐编码:D

票数 2
EN

Stack Overflow用户

发布于 2012-12-17 18:18:05

只要在viewPager.setonpagechangelistener中使用并实现所需代码即可应用您的应用程序,

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13910826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档