繁体   English   中英

ViewPager + FragmentStatePagerAdapter +方向更改

[英]ViewPager + FragmentStatePagerAdapter + orientation change

我有一点问题:我有一些带有一些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;
    }

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

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

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

不要使用 mViewPager.setSaveEnabled(false);

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

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

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

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

我找到了一些解决方案

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

  2. 使用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 /安卓/支持/支持片段/ 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中使用并实现require代码应用你的应用程序,

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM