使用 FragmentStatePagerAdapter 在 ViewPager 的两侧动态添加片段
Posted
技术标签:
【中文标题】使用 FragmentStatePagerAdapter 在 ViewPager 的两侧动态添加片段【英文标题】:Adding Fragments Dynamically on both side of the ViewPager using FragmentStatePagerAdapter 【发布时间】:2014-12-25 07:28:36 【问题描述】:在我的一个应用程序中,我需要在 ViewPager 的两侧添加 Fragments。首先,我将获得 5 个提要的常量,我的 ViewPager 将在索引 2 处显示提要,即我当前显示的片段将包含索引 2 处的数据。所以总的来说,我的 ViewPager 将在开始时显示 5 个提要的中心,并且我只需像这样将 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();
现在的问题是,如果我只在右侧添加提要,即在提要列表的末尾,一切正常,但是当我在零索引处添加提要时,问题就来了。我的适配器没有显示已添加到零位置的新提要,而是重复现有提要之一,并且在右侧但不在左侧重复。我已经尝试了一切,但没有什么是正确的。这是我的适配器代码。
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);
的代码
我认为这与这个问题没有任何关系
我也面临同样的问题。
【参考方案1】:
我之前也遇到过类似的问题,我的解决方法是:
-
首先列表是在适配器本身中声明的,因此在创建该适配器的实例时我可以拥有它自己的列表。
修改了适配器类中的
getItem(int arg0)
方法,使其根据项目位置从列表中返回特定项目。
创建新片段时,使用实例化方法创建它,然后将其添加到您的片段中。
所以,完整的解决方案是:
适配器类:
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 ArrayList 或者我应该有一个 ArrayList 数据并在每次添加新提要时通知该 arrayList ?? 我认为您不必只是将数据添加到ArrayList
并通知更改,我相信分段不会那么顺利,采用片段 ArrayList
或任何其他让您重新创建的方式从头开始的片段,以确保您的所有更改都将得到应用。
我不知道,但如果这是问题所在,那么我将无法在最后添加提要。所以它也应该这样工作。无论如何,我也试过你的,但导致我例外。我已经搜索了例外,但一切都是徒劳的。所以最后我决定暂时每次都设置适配器。
hmmm.. 让我们看看.. 等待正确的答案。反正谢谢。你的帮助真的很可观.. :)
@MuhammedRefaat ***.com/questions/40149039/… 需要帮助【参考方案2】:
FragmentStatePagerAdapter 在前面添加新的 Fragment 时无法正确处理。
解决方法是这样的:
-
在末尾添加一个新片段。
调用 notifyDataSetChanged();
将片段放在前面。
调用 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 不能处理添加到前面的对象吗?以上是关于使用 FragmentStatePagerAdapter 在 ViewPager 的两侧动态添加片段的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)