127

我无法在 FragmentPagerAdapter 中重用片段 .. 使用 destroyItem() 方法,它正在删除片段但仍然没有再次调用 getItem() .. 只有 2-3 个图像,所以我使用 FragmentPagerAdapter 而不是 FragmentStatePagerAdapter ..

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

在 FragmentActivity 中,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 
4

7 回答 7

314

亲吻答案:

简单地使用FragmentStatePagerAdapter而不是FragmentPagerAdapter

我得到了答案。首先我想删除这个问题,因为我犯了一个非常愚蠢的错误,但是这个答案将帮助那些面临同样问题的人,而不是FragmentPagerAdapter使用FragmentStatePagerAdapter

正如评论中提到的@BlackHatSamurai:

这样做的原因是因为FragmentStatePagerAdapter销毁为未使用的片段。FragmentPagerAdapter才不是。

于 2012-09-25T12:00:25.473 回答
171

使用 aFragmentStatePagerAdapter并不能完全解决我的问题,这是一个类似的问题,onCreateView在视图寻呼机中没有为子片段调用。我实际上将我的内部嵌套FragmentPagerAdapter在另一个内部,Fragment因此FragmentManager它们在所有这些中共享,从而保留了旧片段的实例。解决方法是改为将 的实例提供给我的主机片段中getChildFragmentManager的构造函数。FragmentPagerAdapter就像是...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

getChildFragmentManager()方法可以通过片段访问,这对我有用,因为它返回FragmentManager该片段的私有,专门用于需要嵌套片段的情况。我希望这对可能遇到与我相同问题的人有所帮助!

  • 但是请记住,使用getChildFragmentManager()您的最低 API 版本必须至少为17 (4.2),因此这可能会给您带来麻烦。当然,如果您使用支持库 v4 中的片段,您应该没问题。
于 2015-04-16T05:33:32.657 回答
9

覆盖long getItemId (int position)

FragmentPagerAdapter缓存它使用创建的片段getItem。我面临着同样的问题 - 即使notifyDataSetChanged() getItem没有打电话。

这实际上是一个功能,而不是一个错误。您需要覆盖getItemId,以便您可以正确地重用您的片段。由于您正在移除碎片,因此您的位置正在改变。如文档中所述:

long getItemId (int position)

返回给定位置的项目的唯一标识符。

默认实现返回给定的位置。如果项目的位置可以更改,子类应覆盖此方法。

只需为每个片段提供一个唯一的 id 即可。

使用 aFragementStatePagerAdapter或返回POSITION_NONEint getItemPosition (Object object)错误的。你不会得到任何缓存。

于 2018-02-16T15:17:26.240 回答
5

我做了@kanika 和@Jraco11 发布的内容,但我仍然遇到了问题。

因此,经过大量更改后,我找到了一个对我有用的,并将下一个代码添加到我的 FragmentPagerAdapter 中:

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

根据我阅读的内容,getItemPosition用于通知ViewPager是否刷新项目,并在可见位置的项目没有更改的情况下避免更新。

于 2016-04-28T02:39:41.730 回答
4

方法getItem()仅用于创建新项目。一旦他们创建,这个方法将不会被调用。如果您需要获取适配器当前正在使用的项目,请使用此方法:

pagerAdapter.instantiateItem(viewPager, TAB_POS)
于 2018-10-30T10:23:08.203 回答
2

有两种不同的情况: 1.) 每个寻呼机都有相同的布局:在这种情况下,最好通过 PagerAdapter 扩展自定义适配器并返回单个布局。

2.) 每个寻呼机都有不同的布局:在这种情况下,最好通过 FragmentStatePagerAdapter 扩展自定义适配器并为每个寻呼机返回不同的片段。

于 2015-01-21T09:37:23.280 回答
0

我发现在选项卡布局上设置一个侦听器会阻止它被调用,可能是因为它们只有一个侦听器的空间tabLayout.setOnTabSelectedListener而不是一组侦听器。

于 2016-02-04T07:19:29.593 回答