ViewPager无法保存Fragment状态

3
首先,我想感谢stackoverflow社区。多亏了你们,我解决了很多问题!通常我会在这里找到解决方法(98%的时间)。这次我想分享我的问题。
这是我开发的第一个应用程序。我只有一个活动(这是不好的吗?)。我的应用程序结构如下:导航抽屉包含四个项目 - 两个视图翻页器和两个静态片段。视图翻页器包含带有数据列表的列表,如果您单击列表中的某个项,则会呈现详细页面,该页面再次是视图翻页器。当您在详细页面上时,可以单击并转到其他片段。问题是,当我前进到另一个片段时,没有为viewpagerdetails调用onSavedInstance,因此无法保留片段状态。如果我传递getFragmentManager()而不是getChildFragmentManager()给FragmentPagerAdapter,那么将调用onSavedInstance,但如果我这样做,当我回退时,viewpager项为空白。我已尝试使用FragmentStatePagerAdapter,但是当我从“其他片段”点击返回以返回viewpager详细信息时,应用程序崩溃并显示以下错误:Fragment no longer exists for key f0:index 0。我已经在互联网上搜索过,但是我没有找到可行的解决方案。有人说问题来自于适配器,但我尝试了这个解决方案,它不起作用。此外,我想手动保留我的碎片状态,请不要向我提供在应用程序清单中使用configchanges的解决方法。我已尝试从onStop方法调用onSavedInstanceState,但是当我返回到片段时,保存的状态为空。我应该在MainActivity中实现静态变量吗?
FragmentPagerAdapter:
public class DetailsSlideAdapter extends FragmentPagerAdapter {
private String[] navMenuTitles;
private FragmentManager manager;
private FragmentTransaction mCurTransaction = null;
private Resources res;

public DetailsSlideAdapter(FragmentManager fm, Resources res) {
    super(fm);
    this.manager = fm;
    navMenuTitles = res.getStringArray(R.array.detailTabs);
    this.res = res;
}

@Override
public int getCount() {
    return 3;
}


@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            DetailsInfo info = new DetailsInfo();
            return info;
        case 1:
            DetailsCast cast = new DetailsCast();
            return cast;
        case 2:
            DetailsOverview overview = new DetailsOverview();
            return overview;
        default:
            return null;
    }

}

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
        case 0:
            return navMenuTitles[0];
        case 1:
            return navMenuTitles[1];
        case 2:
            return navMenuTitles[2];
        default:
            return navMenuTitles[1];
    }
}

ViewPager详情:

    @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // Get the ViewPager and set it's PagerAdapter so that it can display items
    DetailsSlideAdapter = new DetailsSlideAdapter(getChildFragmentManager(), getResources());
    mViewPager = (ViewPager) rootView.findViewById(R.id.DetailsPager);
    mViewPager.setOffscreenPageLimit(3);
    mViewPager.setAdapter(DetailsSlideAdapter);

    // Give the SlidingTabLayout the ViewPager, this must be done AFTER the ViewPager has had
    // it's PagerAdapter set.
    mSlidingTabLayout = (DetailsSlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
    mSlidingTabLayout.setViewPager(mViewPager);
    mSlidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.tabSelected));
}

如果需要其他代码,我将发布它。谢谢。
使用FragmentStateAdapter进行编辑: 应用程序崩溃:Fragment no longer exists for key f0: index 0。在互联网上,人们说问题来自于适配器,但我尝试了这个解决方案,它没有起作用。代码:
public class DetailsSlideAdapter extends FragmentStatePagerAdapter {
private String[] navMenuTitles;
private FragmentManager manager;
private FragmentTransaction mCurTransaction = null;
private Resources res;
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();


public DetailsSlideAdapter(FragmentManager fm, Resources res) {
    super(fm);
    this.manager = fm;
    navMenuTitles = res.getStringArray(R.array.detailTabs);
    this.res = res;
}

@Override
public int getCount() {
    return 3;
}


@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            DetailsInfo info = new DetailsInfo();
            return info;
        case 1:
            DetailsCast cast = new DetailsCast();
            return cast;
        case 2:
            DetailsOverview overview = new DetailsOverview();
            return overview;
        default:
            return null;
    }

}

@Override
public CharSequence getPageTitle(int position) {
    switch (position) {
        case 0:
            return navMenuTitles[0];
        case 1:
            return navMenuTitles[1];
        case 2:
            return navMenuTitles[2];
        default:
            return navMenuTitles[1];
    }
}


@Override
public Object instantiateItem(ViewGroup container, int position) {
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    registeredFragments.remove(position);
    super.destroyItem(container, position, object);
}

public Fragment getRegisteredFragment(int position) {
    return registeredFragments.get(position);
}

3
将您的适配器从FragmentStatePagerAdapter继承。 - savepopulation
你找到任何解决方案了吗? - CodingRat
目前我正在使用FragmentStatePagerAdapter,但是遇到了错误:“Fragment no longer exists for key f0:index 0”。此外,由于未调用onSaveInstanceState,我不得不编写自己的backStack。 - Radoslav Yordanov
1个回答

1

你看过这个吗?FragmentStatePagerAdapter

来自文档:

PagerAdapter的一种实现,使用Fragment来管理每个页面。这个类还处理片段的保存和恢复状态。


感谢您的回答。正如我在问题中所说:我尝试使用FragmentStatePagerAdapter,但当我从“其他片段”返回到viewpager详细信息时,应用程序崩溃,并显示以下错误:Fragment no longer exists for key f0: index 0。此外,我注意到onSavednstance状态没有被调用。 - Radoslav Yordanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接