38

目前,FragmentActivity我使用以下代码在两种类型的片段之间切换。

private void toggle() {
    Fragment oldFragment = getSupportFragmentManager().findFragmentById(R.id.content);
    Fragment fragment = null;
    if (oldFragment instanceof ColorFragment) {
        fragment = new ViewPagerFragment();
    } else {
        fragment = new ColorFragment(android.R.color.black);
    }

    getSupportFragmentManager().beginTransaction().replace(R.id.content, fragment).commitAllowingStateLoss();
}

2 个片段正在切换。

  • ColorFragment - 一个简单的片段,它用纯黑色填充其背景。
  • ViewPagerFragment - 一个片段包含ViewPager. 用户可以在紫色片段和蓝色片段之间滑动。

负责刷紫色和蓝色碎片的代码如下。

private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            return new ColorFragment(android.R.color.holo_purple);
        default:
            return new ColorFragment(android.R.color.holo_blue_bright);
        }
    }      
} 

但是,我在切换过程中遇到了奇怪的行为。

  1. 显示黑色片段。
  2. 切换。
  3. 查看寻呼机,它可以在显示的紫色和蓝色片段之间滑动。
  4. 切换。
  5. 显示黑色片段。
  6. 切换。
  7. 没有显示任何内容,因为未触发 MyFragmentPagerAdapter 的 getItem。

我想我的情况类似于FragmentPagerAdapter getItem is not called

但是,我不喜欢使用FragmentStatePagerAdapter,因为在页面之间切换时可能会产生更多开销。

有什么办法可以克服这个问题吗?

我包含一个完整的可行源代码来演示这个问题:https ://www.dropbox.com/s/jok9tz5ktvfcteo/viewpagerbug.zip

4

5 回答 5

112

有什么办法可以克服这个问题吗?

我已经下载了您的代码并且出现了问题,因为您没有Fragments正确处理这些代码。最准确地说,您使用嵌套FragmentsViewPager基础中Fragment并为此ViewPager创建适配器,如下所示:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getFragmentManager());

相反,您应该使用getChildFragmentManager()来绑定嵌套片段:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

此外,您不应该通过构造函数将数据传递给 a Fragment,因为该数据将无法在配置更改后继续存在,并且会开始出现坏事。改用 a Bundle

于 2013-03-23T16:04:58.470 回答
12

全球工作测试解决方案。

getSupportFragmentManager()有时会保留空引用,View pager 不会创建新的片段实例。因为它找到了对同一片段的引用。所以要克服这种使用getChildFragmentManager()以简单的方式解决问题。

new PagerAdapter(getSupportFragmentManager(), fragments);

new PagerAdapter(getChildFragmentManager() , fragments);

于 2015-01-28T06:39:07.733 回答
2

简单使用FragmentStatePagerAdapter代替FragmentPagerAdapter

或者

您可以使用new MyFragmentPagerAdapter(this.getChildFragmentManager())

希望它会帮助你:)

于 2016-06-20T13:36:47.250 回答
1

就我而言,我正确地打电话

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

但随后在嵌套片段中,我尝试使用以下方法将容器片段替换为另一个片段:

getFragmentManager()

您需要参加活动并致电

getActivity().getSupportFragmentManager();
于 2015-11-11T13:34:30.803 回答
0

在我的情况下,将其添加到我的FragmentPagerAdapter后它起作用了:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

我也像 Luksprog 所说的那样使用了getChildFragmentManager()

于 2016-04-28T02:43:05.463 回答