我想要达到的目标:
一个带有 ViewPager 的 Activity,它显示适配器 ( FragmentStatePagerAdapter
) 中对象列表的片段。
最初,Activity 将 SQLite DB 中的 N 个(比如说 5 个)对象加载到适配器中。这些对象是随机选择的。
当用户到达列表末尾时,活动应从数据库加载 M(假设 M 为 3)更多对象,将它们添加到适配器并调用notifyDataSetChanged()
. 添加它们时,我检查列表中是否已经存在新对象,如果存在,则删除预先存在的对象,并将加载的对象添加到列表的尾部。
因此,我试图实现类似无限滚动 ViewPager的东西(不是“循环” ViewPager,因为我希望不断地获取新对象,而不是回到列表的乞讨)。
我有一些工作代码,并包含了我在下面遵循的模式的示例。但是,我不断收到此异常,不知道为什么:
IllegalStateException: Fragment MyObjectFragment{id...} is not currently in the FragmentManager
at android.app.FragmentManagerImpl.saveFragmentInstanceState(FragmentManager.java:553)
at android.support.v13.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:140)
at android.support.v4.ViewPager.populate(ViewPager.java:1002)
...
代码示例:
活动:
public class MyActivitty extends FragmentActivity {
public MyPagerAdapter adapter;
public ViewPager pager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_acyivity_layout);
pager = (ViewPager) findViewById(R.id.viewPager);
ArrayList<MyObject> myObjects = new ArrayList<MyObject>();
// loadInitialObjectsFromDB(int N) goes to SQLite DB and loads the N first objects to show on the ViewPager...
myObjects = loadInitialObjectsFromDB(5);
// Adapter will use the previously fetched objects
adapter = new MyPagerAdapter(this, getFragmentManager(), myObjects);
pager.setAdapter(adapter);
pager.setOffscreenPageLimit(2);
// (...)
}
// (...)
}
寻呼机适配器:
public class MyPagerAdapter extends FragmentStatePagerAdapter implements
ViewPager.OnPageChangeListener {
private MyActivity context;
private ArrayList<MyObject> objectList;
private int currentPosition = 0;
// (...)
public MyPagerAdapter(MyActivity context, FragmentManager fragmentManager, ArrayList<MyObject> objects)
{
super(fragmentManager);
this.context = context;
this.objectList = objects;
}
@Override
public Fragment getItem(int position)
{
MyObject object = objectList.get(position);
return MyObjectFragment.newInstance(position, object);
}
@Override
public int getItemPosition(Object object){
MyObjectFragment frag = (MyObjectFragment) object;
MyObject object = frag.getMyObject();
for(int i = 0; i < objectList.size(); i++)
{
if(objectList.get(i).getId() == object.getId())
{
return i;
}
}
return PagerAdapter.POSITION_NONE;
}
@Override
public int getCount()
{
return objectList.size();
}
@Override
public void onPageSelected(int position)
{
currentPosition = position;
}
// (...)
}
@Override
public void onPageScrollStateChanged(int state)
{
switch(state)
{
case ViewPager.SCROLL_STATE_DRAGGING:
// (...)
break;
case ViewPager.SCROLL_STATE_IDLE:
// if we are reaching the "end" of the list (while scrolling to the right), load more objects
if(currentPosition <= position && position >= answerList.size()-1)
{
// Function in MyActivity that fetches N more objects.
// and adds them to this adapter's ArrayList<MyObject> objectList
// it checks for duplicates so that if the fetched object was already in the back of the list, it is shown again
context.getMoreObjects(3);
notifyDataSetChanged();
}
getMoreQuestions(currentPosition);
case ViewPager.SCROLL_STATE_SETTLING:
break;
}
}
我的片段:
public class MyObjectFragment extends Fragment {
// Object to represent
private MyObject object;
public static Fragment newInstance(MyActivity context,
int position, MyObject object) {
MyObjectFragment frag = new MyObjectFragment();
Bundle args = new Bundle();
args.putParcelable("Object", object);
frag.setArguments(args);
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.currentInflater = inflater;
final View rootView = inflater.inflate(
R.layout.fragment_my_object, container, false);
// get object from Bundle, set UI, events, etc...
}
// (...)
}
关于我为什么会得到这个的任何想法Exception
?似乎他们FragmentStatePagerAdapter
正在试图摧毁一个不再存在的项目,但我不明白为什么。
编辑1:
如果我评论我的@Override getItemPosition(Object object)
,我不会再得到例外。但是,我需要覆盖getItemPosition
,因为有一个用例,其中用户删除当前显示的 Object 导致它从适配器的数组中消失,并在该项目不再存在时强制getItemPosition
返回。POSITION_NONE
编辑2:
现在我知道只有当我从适配器的objectList
. 我有两种情况,其中MyObject
实例被删除objectList
:
当
getMoreObjects()
添加从数据库中获取已经在 中的对象时objectList
,我将其删除并将其重新添加到列表的头部。我这样做是为了避免在 objectList 中有具有相同 ID 的对象,因为它们的 ID 被用于getItemPosition()
了解它们是否存在以及它们的位置。在返回之前,
getMoreObjects()
从列表中删除前 N 个对象。我知道 FragmentStatePagerAdapter 已经通过仅保留某些对象的内存片段来节省内存,但我仍然想避免增长objectList
太多。现在,我已经评论了这一行,因为它并不那么重要。