15

我正在使用 ViewPageIndicator 中的ViewPager,我需要能够在其他片段中间动态插入一个片段。

我尝试使用FragmentPagerAdapterFragmentStatePagerAdapter(均来自 v4 支持代码)管理模型,第一个似乎不以任何方式管理在中间插入页面。第二个方法只有在我简单地实现getItemPosition总是返回 POSITION_NONE 时才有效,但这会导致我每次滑动时都完全重新创建页面。

我用 FragmentStatePagerAdapter (FSP) 观察到的问题是:

  • 我从两页开始 [A][B]
  • 然后我在中间 [A][C][B] 中插入 [C]。插入后我调用notifyDataSetchange()
  • 然后 FSP 为 [A] 调用 getItemPosition 并得到 0
  • 然后 FSP 为 [B] 调用 getTItemPosition 并得到 2。它说......哦,我必须销毁 [B] 并制作 mFragments.set(2, null) 然后因为它在 mFragments 数组中只有两个元素,所以它抛出IndexOutOfBoundsException

在代码中看了一点之后,似乎提供的 fragmentStatePagerAdapter 不支持在中间插入。这是正确的还是我错过了什么?

更新: 适配器中的插入是以逻辑方式进行的,当某个代码为真时,页面会增加一。片段创建是使用 getItem() 中的构造函数以这种方式完成的:

void setCondition(boolean condition) {
   this.condition=condition;
   notifyDataSetChanged();
}
public int getCount(){
    return condition?3:2;
}
public Fragment getItem(int position) {
    if(position==0) 
        return new A();
    else if(position==1)
        return condition?new C():new B();
    else if(position==2 && condition)
        return new B();
    else throw new RuntimeException("Not expected");
}
public int getItemPosition(Object object) {
    if(object instanceof A) return 0;
    else if(object instanceof B) return condition?2:1;
    else if(object instanceof C) return 1;
} 

解决方案:

正如在接受的答案中所说,关键是实施getItemId()

确保至少使用R9(2012 年 6 月)版本的 android-support library。因为里面加了这个方法。在此版本之前,该方法不存在,并且适配器无法正确管理插入。还要确保使用FragmentPageAdapter,因为 FragmentStatePagerAdapter 仍然不起作用,因为它不使用 id。

4

1 回答 1

5

你忘记了一种方法。
覆盖getItemId(int position)从中FragmentPagerAdapter简单地返回位置以返回将识别片段实例的内容。

public long getItemId(int position) {
    switch (position) {
    case 0:
        return 0xA;
    case 1:
        return condition ? 0xC : 0xB;
    case 2:
        if (condition) {
            return 0xB;
        }
    default:
        throw new IllegalStateException("Position out of bounds");
    }
}
于 2012-07-27T09:46:50.933 回答