使用FragmentStatePagerAdapter从ViewPager动态删除项目

时间:2015-01-23 11:29:42

标签: android android-fragments android-viewpager android-adapter

围绕这个主题进行了不少讨论

我尝试了各种解决方案(包括POSITION_NONE失效) 。但我仍然不知道如何正确删除项目。

会发生什么

  • 要么我得到一个空白页面(意味着片段被破坏,但是 instantiateItem没有被要求替换)
  • 或整个事情崩溃可能是因为Android管理的方式 片段实例与我将它们保存在我的方式中的方式不匹配 arraylist/sparsearray

这是我的适配器

private class DatePickerPagerAdapter extends FragmentStatePagerAdapter {

    ArrayList<Fragment> registeredFragments = new ArrayList<Fragment>();

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

    @Override
    public Fragment getItem(int position) {
        return CreateWishFormDatePaginationFragment.newInstance(position);
    }

    @Override
    public int getItemPosition(Object object){ //doesnt change much.. 
        return PagerAdapter.POSITION_NONE;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.add(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, registeredFragments.get(position));
    }

    public void removePage(ViewGroup pager, int position) {
        destroyItem(pager, position, null);
        registeredFragments.remove(position);
        iPageCount--;
        pagerIndicator.notifyDataSetChanged();
        pagerAdapter.notifyDataSetChanged();
    }

    public void addPage() {

        iPageCount++;
        pagerIndicator.notifyDataSetChanged();
        pagerAdapter.notifyDataSetChanged();
    }
}

我正在使用带有ViewPagerIndicator的视图寻呼机,我希望能够删除其间的页面,例如。

因此仍然是一个问题,在ViewPager中处理片段的添加和删除的正确方法是什么?

谢谢!

2 个答案:

答案 0 :(得分:18)

如果您要从ViewPager中删除项目,则以下代码没有意义:

@Override
public Fragment getItem(int position) {
    return CreateWishFormDatePaginationFragment.newInstance(position);
}

基本上,您根据Fragment创建position。无论您移除哪个页面,position的范围都会从 [0,iPageCount更改为 [0,iPageCount-1,这意味着它将永远摆脱最后的Fragment

您需要的是或多或少的以下内容:

public class DatePickerPagerAdapter extends FragmentStatePagerAdapter
{
    private ArrayList<Integer> pageIndexes;

    public DatePickerPagerAdapter(FragmentManager fm) {
        super(fm);
        pageIndexes = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            pageIndexes.add(new Integer(i));
        }
    }

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

    @Override
    public Fragment getItem(int position) {
        Integer index = pageIndexes.get(position);
        return CreateWishFormDatePaginationFragment.newInstance(index.intValue());
    }

    // This is called when notifyDataSetChanged() is called
    @Override
    public int getItemPosition(Object object) {
        // refresh all fragments when data set changed
        return PagerAdapter.POSITION_NONE;
    }

    // Delete a page at a `position`
    public void deletePage(int position)
    {
        // Remove the corresponding item in the data set 
        pageIndexes.remove(position);
        // Notify the adapter that the data set is changed
        notifyDataSetChanged();
    }
}

有关从FragmentStatePagerAdapter 中移除项目的详细信息,请参阅此完整的example

答案 1 :(得分:6)

ViewPager不会使用上面的代码删除您的片段,因为它会将多个视图(或您的案例中的片段)加载到内存中。除了可见视图外,它还将视图加载到可见视图的任一侧。这提供了从视图到视图的平滑滚动,使ViewPager变得如此酷。

要达到你想要的效果,你需要做一些事情。

  1. 将FragmentPagerAdapter更改为FragmentStatePagerAdapter。这样做的原因是FragmentPagerAdapter会将它加载的所有视图永久保存到内存中。 FragmentStatePagerAdapter处理位于当前和可遍历视图之外的视图。
  2. 覆盖适配器方法getItemPosition(如下所示)。当我们调用mAdapter.notifyDataSetChanged(); ViewPager询问适配器以确定在定位方面发生了哪些变化。我们使用此方法表示所有内容都已更改,因此重新处理所有视图定位。 这是代码......

    private class MyPagerAdapter extends FragmentStatePagerAdapter {
        //... your existing code
        @Override
        public int getItemPosition(Object object){
            return PagerAdapter.POSITION_NONE;
        }
    }