2

我想在我的 ViewPager 的第一页中添加一个新视图。我的适配器如下所示:

public class PagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> fragments;

    public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int index) {
        return fragments.get(index);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    public void add(int i, ImageFileObject imageFile) {
        ImageViewFragment f = new ImageViewFragment();
        f.setImage(imageFile);
        fragments.add(0, f);
        notifyDataSetChanged();
    }

    public void add(ImageFileObject imageFile) {
        ImageViewFragment f = new ImageViewFragment();
        f.setImage(imageFile);
        fragments.add(f);
        notifyDataSetChanged();
    }

}

但是在调用 add(0, aImageFile) 时,该项目不会添加到片段列表中。(它甚至没有附加)。

有任何想法吗?

4

2 回答 2

2

更新:您在评论中描述的问题是真实的,我在第一次测试时错过了它。在分析了源代码后,FragmentPagerAdapter我意识到我们需要做的就是以一种不会为不同的片段项返回相同 id 的方式进行覆盖。getItemId()例如,当前的默认实现只会将位置作为片段的 id 返回,这不适用于这种情况:

 public long getItemId(int position) {
    return position;
}

我正在更新这个答案,请看一下。和以前一样,我已经测试了这段代码,你描述的问题现在没有发生。


您唯一需要做的就是不要自己保留对片段的引用List,这是由FragmentPagerAdapter. 据我所知,这也不是一个好习惯。而且即使您按照其他答案的建议返回POSITION_NONEgetItemPosition()您最终也会遇到异常

原因:java.lang.IllegalStateException:无法更改片段的标记。

这是因为您试图通过在第 0 个索引处添加一个片段(这会导致其他片段重新定位)并根据位置分配标签来重新Fragment定位Listalive ViewPager

牢记这一切,这是一个经过测试且可以工作的修改后的适配器:

public class PagerAdapter extends FragmentPagerAdapter {
public static class FragmentInfo {
    public String classz;
    public ImageFileObject imageFile;


    public static long IDS;
    public long id;

    public FragmentInfo(){
        id = IDS++;
    } 
}



private final List<FragmentInfo> fragments;
private Context context;

public PagerAdapter(FragmentManager fm, List<FragmentInfo> fragments,
        Context context) {
    super(fm);
    this.fragments = fragments;
    this.context = context;
}

@Override
public Fragment getItem(int index) {
    FragmentInfo info = fragments.get(index);
    ImageViewFragment frag = (ImageViewFragment) Fragment.instantiate(
            context, info.classz, /* null arguments*/ null);
    frag.setImage(info.imageFile);
    return frag;
}

@Override
public long getItemId(int position) {
    return fragments.get(position).id;
} 

@Override
public int getCount() {
    return fragments.size();
}

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

public void add() {
    FragmentInfo f = new FragmentInfo();
    f.classz = ImageViewFragment.class.getName();
    fragments.add(0, f);
    notifyDataSetChanged();
}
}

请相应地更改您的代码。

于 2013-10-09T16:44:13.497 回答
0

问题实际上出在 notifyDataSetChanged 上。只需添加到您的适配器:

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

但是,我认为当适配器实际尝试getItem再次调用时,您会遇到其他问题。这些问题将出现在“已添加片段”的行中。

于 2013-10-09T14:51:12.507 回答