首页 文章

ViewPager FragmentStatePagerAdapter方向更改

提问于
浏览
10

我有一点问题:我有一些带有一些Pages的ViewPager,我使用FragmentStatePagerAdapter来处理数据 . 在肖像中,我有例如20页用于ViewPager,在景观中我只有10页用于ViewPager . 因此,在方向更改时,我创建了一个具有不同数据的新适配器 .

这里有一个小解释原因:我在肖像中展示一幅图像,在风景中展示两幅图像,但总是全部都在计算中如果我要显示10张照片,我有10张照片,5张照片(总是两张) .

但现在我有一个奇怪的错误:当我在索引5上的Landscape并转动设备时,ViewPager的当前页面设置为10.如果我再将它再次转回我在第5页 . 如果我现在将ViewPage刷到页面10从不调用适配器的methode getItem,并且ViewPage向我显示一个肖像图片而不是两个用于横向图片 . 怎么会发生这种情况?适配器或ViewPager中是否有缓存?在Activity的onCreate中,一切都是新创建的,适配器以及ViewPager的数据(只是带路径的字符串) . 所以任何想法如何解决这个真正可怕的“功能”?

这是一些代码:

的onCreate:

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

adapter 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;
    }

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

3 回答

  • -1

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

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

    Do not use mViewPager.setSaveEnabled(false);

    它结束了一个很大的记忆泄漏 . 每次更改方向后,它都会将Fragments放入FragmentManager数组中,并且永远不会清除它 . 因此,多次更改方向后,内存使用量将超过100mb . 使用onSaveInstanceState方法是我认为更好的方法 .

  • 0

    我也发生了这个问题,我找到了原因 .

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

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

    我找到了一些解决方案

    • 不要调用你的 super.onSaveInstanceState() 活动,但是's seems not a good solution, Fragments can' t保存状态并恢复 .

    • 使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter . 但是在方向改变之后, ViewPager 托管的片段被消隐了(有没有其他人有同样的问题?) . 但我可以删除 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() 召唤了两次 .

    我仍然在寻找完美的解决方案: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添加到活动布局XML,它是固定的 .

    编码快乐:D

  • 41

    只是你在viewPager.setonpagechangelistener中使用并实现require代码应用你的应用程序,

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

相关问题