在FragmentPageAdapter的中间插入页面

luj*_*jop 15 android android-adapter android-viewpager viewpagerindicator

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

我试图用FragmentPagerAdapterFragmentStatePagerAdapter(都来自v4支持代码)管理模型,第一个似乎不管理中间插入页面的任何方式.第二个只有当我做一个天真的getItemPosition实现返回总是POSITION_NONE但这会导致每次刷卡时完全重新创建页面.

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

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

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

更新: 适配器中的插入是以逻辑方式进行的,当某个编码为真时,页面会增加1.片段创建是使用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;
} 
Run Code Online (Sandbox Code Playgroud)

解:

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

确保至少使用R9(2012年6月)版本的android-support库.因为这个方法已添加到其中.在此版本之前,该方法不存在,并且适配器无法正确插入插入.还要确保使用FragmentPageAdapter,因为FragmentStatePagerAdapter仍然不起作用,因为它不使用id.

paw*_*eba 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");
    }
}
Run Code Online (Sandbox Code Playgroud)