使用FragmentStatePagerAdapter在ViewPager两侧动态添加片段

6
在我的一个应用程序中,我需要在ViewPager的两侧添加Fragments。首先,我会获取5个feeds的常量,我的ViewPager将显示索引为2的feed,即当前显示的Fragment将包含索引为2的数据。因此,总体上,我的ViewPager将在开始时显示5个feeds的中心,并且我通过设置ViewPager当前项为2来实现了这一点,就像这样:
viewPager.setCurrentItem(2);

现在用户可以在两个方向上滑动。当他从中间位置向左滑动时,我将查找下一条反馈,即从服务器获取反馈并将其添加到我的ViewPager的零索引处,如下所示:

feedsList.add(0, modelClassObject); // feedsList will contain all feeds and has been used by adapter to show data in fragments.
adapter.notifyDataSetChanged();

当我从中心位置向右滑动时,我会将新的信息源添加到最后,就像这样。
feedsList.add(modelClassObject);
adapter.notifyDataSetChanged();

现在问题是,如果我只在feedsList的末尾添加feed,一切都正常,但是当我在零索引处添加feed时,问题就出现了。我的适配器没有显示已添加到零位置的新feed,而是重复了其中一个现有的feed,而且还在右侧而不是左侧。我已经尝试了一切,但是没有什么是正确的。以下是我的适配器代码。

private class HorizontalPagerAdapter extends FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int arg0) {
        return FeedUserProfileFragment.newInstance(feedsList.get(arg0),
                arg0);
    }

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

}

我也使用过这个

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

但是没有结果... :(

所以我急需帮助,如果有人之前已经做过并遇到了同样的问题,请告诉我我做错了什么。我只需要在我的ViewPager的零索引处添加片段。


发布代码 FeedUserProfileFragment.newInstance(feedsList.get(arg0),arg0); - mmlooloo
我认为那与这个问题没有任何关系。 - Mukesh Rana
我也遇到了同样的问题。 - Neeraj
2个回答

4
我之前遇到过相似的问题,我的解决方案如下:
  1. 首先,在适配器中声明列表List,这样当创建适配器实例时我就能拥有它自己的列表。
  2. 修改适配器类中的方法getItem(int arg0),让其根据项目位置返回特定项目列表中的一个项目。
  3. 在创建新片段时,使用instantiate方法进行创建,并将其添加到您的片段中。
因此,完整的解决方案如下: 适配器类:
private class HorizontalPagerAdapter extends FragmentStatePagerAdapter {

public List<Fragment> feedsList;

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

    @Override
    public Fragment getItem(int position) {
        return feedsList.get(position);
    }

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

}

在创建适配器时:

public static YourPageAdapter adapter_obj; // make sure it's static object
adapter_obj =  new YourPageAdapter(getSupportFragmentManager());
adapter_obj.feedsList = new ArrayList<Fragment>();
// then add the list of fixed fragments to it(the 5 in the beginning)
adapter_obj.feedsList = fragments_list; // an ArrayList contains the 5 fragments

如果想要创建新的片段:

adapter_obj.feedsList.add(0, Fragment.instantiate(mContext, ViewPager_Container_Class.class.getName(), page));
adapter_obj.notifyDataSetChanged();

其实我只使用了一个Fragment,而且每次其中的数据都会改变。所以您认为我还需要使用Fragment ArrayList,还是应该有一个数据ArrayList,并在每次添加新的feed时通知该ArrayList? - Mukesh Rana
我认为你不能只是向ArrayList添加数据并通知更改,我相信这种方式在分段时不会很好,最好采用片段ArrayList或其他使您能够从头开始重新创建片段以确保所有更改都被应用的方法。 - Muhammed Refaat
1
我不知道,但如果那是问题的话,那么我就无法在最后添加源。所以它也应该按那种方式工作。无论如何,我也尝试了你的方法,但会导致异常。我已经搜索了异常,但一切都徒劳无功。所以最后我决定暂时每次设置适配器。 - Mukesh Rana
嗯...让我们看看...等待正确的答案。无论如何,谢谢。你的帮助真的很可贵.. :) - Mukesh Rana
1
需要帮助。@MuhammedRefaat在stackoverflow上的问题:“RecyclerView仅在片段中显示最后一个ArrayList项”。 - albert

1

当您在前面添加新片段时,FragmentStatePagerAdapter无法正确处理它。

解决方法如下:

  1. 在末尾添加新片段。
  2. 调用notifyDataSetChanged();
  3. 将片段移到最前面。
  4. 再次调用notifyDataSetChanged();

顺便提一下,getItemPosition()应始终返回正确的位置:

public int getItemPosition(Object object)
{
    return feedsList.indexOf( object );
}

所以,根据您的代码,应该是这样的:

newFrag = Fragment.instantiate(...);
feedsList.add( newFrag );
adapter_obj.notifyDataSetChanged();

feedsList.remove( feedsList.size() - 1 );
feedsList.add( 0, newFrag );
adapter_obj.notifyDataSetChanged();

我猜FragmentStatePagerAdapter的实现不会同时添加新片段和更改位置。

能否解释一下为什么FragmentPagerAdpter无法处理添加到前面的对象? - Vivek Av

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接