简体   繁体   English

使用FragmentStatePagerAdapter从ViewPager动态删除项目

[英]Dynamically remove an item from a ViewPager with FragmentStatePagerAdapter

There are quite a few discussions around this topic 关于这个主题有很多讨论

I have tried various solutions (including the invalidation with POSITION_NONE ) . 我尝试了各种解决方案(包括使用POSITION_NONE失效)。 But I still donT know how to remove an item properly. 但我仍然不知道如何正确删除项目。

What happens is 会发生什么

  • either I get a blank page (meaning the fragment is destroyed, but the instantiateItem was not called for a replacement) 要么我得到一个空白页面(意味着片段被销毁,但是instantiateItem项目没有被调用替换)
  • or the whole thing crashes probably because the way the Android manages the fragment instances do not match how I keep them in my arraylist/sparsearray 或整个事情崩溃可能是因为Android管理片段实例的方式与我在arraylist/sparsearray保存它们的方式arraylist/sparsearray

Here s my adapter 这是我的适配器

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();
    }
}

I am using a view pager with ViewPagerIndicator and I want to be able to remove a page in between, for example. 我正在使用ViewPagerIndicator的视图寻呼机,我希望能够删除其间的页面,例如。

Hence remains the question, what is the proper way handling addition and removal of fragments in a ViewPager? 因此,问题是,在ViewPager中处理片段的添加和删除的正确方法是什么?

Thanks! 谢谢!

If you want to remove items from a ViewPager , this following code does not make sense: 如果要从ViewPager删除项目,以下代码没有意义:

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

Essentially, you create a Fragment based on the position . 基本上,您可以根据position创建Fragment No matter which page you remove, the range of the position will change from [0, iPageCount ) to [0, iPageCount-1 ) , which means that it will always get rid of the last Fragment . 无论您移除哪个页面, position范围都会从[0, iPageCount ]更改为[0, iPageCount-1 ,这意味着它将始终摆脱最后一个Fragment


What you need is more or less the following: 您需要的是或多或少以下内容:

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();
    }
}

Please refer to this complete example for more details about removing item from FragmentStatePagerAdapter . 有关从FragmentStatePagerAdapter中删除项目的更多详细信息,请参阅此完整示例

The ViewPager doesn't remove your fragments with the code above because it loads several views (or fragments in your case) into memory. ViewPager不会使用上面的代码删除您的片段,因为它会将多个视图(或您的案例中的片段)加载到内存中。 In addition to the visible view, it also loads the view to either side of the visible one. 除了可见视图外,它还将视图加载到可见视图的任一侧。 This provides the smooth scrolling from view to view that makes the ViewPager so cool. 这提供了从视图到视图的平滑滚动,使ViewPager非常酷。

To achieve the effect you want, you need to do a couple of things. 要达到您想要的效果,您需要做一些事情。

  1. Change the FragmentPagerAdapter to a FragmentStatePagerAdapter. 将FragmentPagerAdapter更改为FragmentStatePagerAdapter。 The reason for this is that the FragmentPagerAdapter will keep all the views that it loads into memory forever. 这样做的原因是FragmentPagerAdapter会将它加载的所有视图永久保存到内存中。 Where the FragmentStatePagerAdapter disposes of views that fall outside the current and traversable views. FragmentStatePagerAdapter处理位于当前和可遍历视图之外的视图。
  2. Override the adapter method getItemPosition (shown below). 覆盖适配器方法getItemPosition(如下所示)。 When we call mAdapter.notifyDataSetChanged(); 当我们调用mAdapter.notifyDataSetChanged(); the ViewPager interrogates the adapter to determine what has changed in terms of positioning. ViewPager询问适配器以确定在定位方面发生了哪些变化。 We use this method to say that everything has changed so reprocess all your view positioning. 我们使用此方法表示所有内容都已更改,因此重新处理所有视图定位。 And here's the code... 这是代码......

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM