【问题标题】:Using viewpager with specific fragments使用带有特定片段的 viewpager
【发布时间】:2015-03-03 21:11:18
【问题描述】:

我正在创建一个使用 viewpager 在 4 个特定片段之间滑动的应用。

到目前为止我读过的所有viewpager的例子,每次调用FragmentPagerAdapter的getPosition方法时都会创建新的片段。所以它是这样的:

return FragmentA.newInstance();

我所做的如下:

在主要活动中

public static final int FRAGMENTS = 4;
public static final String FRAGMENT_LIST ="LIST";
public static final String FRAGMENT_SETTINGS = "SETTINGS";
public static final String FRAGMENT_MAP = "MAP";
public static final String FRAGMENT_TICKET = "TICKET";

MainAdapter _adapter;
ViewPager _pager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager()
                .beginTransaction()
                .add(new FragmentMap(), FRAGMENT_MAP)
                .add(new FragmentList(), FRAGMENT_LIST)
                .add(new FragmentTicket(), FRAGMENT_TICKET)
                .add(new FragmentSettings(), FRAGMENT_SETTINGS)
                .commit();
    }

    _adapter = new MainAdapter(getSupportFragmentManager());
    _pager = (ViewPager) findViewById(R.id.pager);
    _pager.setAdapter(_adapter);
}

在适配器中:

public class MainAdapter extends FragmentPagerAdapter {

FragmentManager _manager;

public MainAdapter(FragmentManager fm) {
    super(fm);
    _manager = fm;
}

@Override
public Fragment getItem(int position) {
    return _manager.getFragments().get(position);
}

@Override
public int getCount() {
    return ActivityMain.FRAGMENTS;
}
}

这会引发异常,因为适配器正在尝试更改 getItem 中每个片段的标记

我的问题是:

a) 每次总是使用同一个片段是不正确的吗?我没有看到使用上述方法或类似方法的示例,它们总是在 getItem 方法中创建一个新实例

b) 如果我希望片段具有一些持久性,那么这是否意味着我应该将每个片段应该保存的数据存储在静态变量中,并始终创建使用这些变量的新实例?

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    a) 您必须在getItem() 方法中创建一个新实例,此方法不会在您每次从视图页面切换片段时调用。

    我建议你像这样使用适配器

    public class MainAdapter extends FragmentPagerAdapter {
    
    public MainAdapter(FragmentManager fm) {
        super(fm);
    }
    
    @Override
    public Fragment getItem(int position) {
                case 0 :
                    return new FragmentMap();
                case 1 :
                    return new FragmentList();
                case 2 :
                    return new FragmentTicket();
                case 3 :
                    return new FragmentSettings();
                default :
                    return null;
    }
    
    @Override
    public int getCount() {
        return ActivityMain.FRAGMENTS;
    }
    }
    

    b) FragmentPagerAdapter 中的 Fragment 是持久化的,只有在 ViewPager 中切换多个 Fragment 时才会重新创建它们。例如,如果您不想在您的情况下重新创建片段,您可以通过 _pager.setOffscreenPageLimit(3); 设置刷新限制。

    欲了解更多信息:http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

    【讨论】:

    • 我已经尝试过了,问题是,当我使用 FragmentPagerAdapter 时,我收到一条错误消息,指出视图已经有父视图,但它可以与 FragmentStatePagerAdapter 一起使用,但我的问题是,一旦我导航在它被删除的特定片段之外,所以我不能通过说 getSupportFragmentManager().getFragments().get(0); 之类的话来使用它。我需要它,因为将来,每个fargment都会与父活动通信并向其发送消息,活动将使用该消息来更新其他片段
    • 对不起,我没有注意到你的 setOffScreenPageLimit 评论,我会试试的,谢谢
    • 我还建议您使用 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter。
    • 只是为了让阅读本文的人清楚,这不是我想要的确切解决方案,但它是帮助我最大程度地实现我想要的解决方案的一个。我所做的是:a)使用setOffScreeenPageLimit(0)设置viewpager,这样它似乎删除了当前片段以外的片段(或者至少它停止抛出片段已经有父片段的异常)b)通过a List 与片段管理器一起与适配器争论,并让 getItem 方法从列表中返回项目,这样我可以引用所有使用的片段
    【解决方案2】:

    a) 我认为这完全没问题。他们总是创建新实例,因为它更容易并且在许多情况下(如图片库)更好。

    b) 如果您将应用程序发送到后台然后返回,静态变量会丢失。共享首选项或捆绑包应该可以完成工作。

    【讨论】:

    • 因此,如果我按照以下方式创建构造函数: public MainAdapter(FragmentManager fm, List Fragment) 然后使用 getItem() 从列表中返回特定项目,它不应该有问题吗?当您说将变量保存到包中时,如果我将片段列表保存到包中然后从 OnCreate 中提取它们会不正确吗?
    【解决方案3】:

    您应该使用 FragmentStatePagerAdapter。如果你使用fragmentstatepager 适配器,你可以动态删除或添加fragment。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-22
      • 1970-01-01
      • 2012-06-06
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 2023-03-17
      相关资源
      最近更新 更多