我在ViewPager中引用我的片段时遇到问题。我想这样做是因为从我的活动中我想在指定位置刷新一个片段(例如当前显示的片段)。
目前我有这样的事情:
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static final String TAG = "MyPagerAdapter";
private static HashMap<Integer, EventListFragment> mPageReferenceMap = new HashMap<Integer, EventListFragment>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
Log.i(TAG, "getItem: "+position);
int dateOffset = position-1;
EventListFragment mFragment = EventListFragment.newInstance(dateOffset);
mPageReferenceMap.put(position, mFragment);
return mFragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.i(TAG, "destroyItem: "+position);
mPageReferenceMap.remove(position);
super.destroyItem(container, position, object);
}
public EventListFragment getFragment(int key) {
Log.i(TAG, "Size of pager references: "+mPageReferenceMap.size());
return mPageReferenceMap.get(key);
}
}
问题是destroyItem()
被调用的频率高于getItem()
,所以我留下了空引用。如果我不使用destroyItem()
来清除对已销毁片段的引用......那么我会引用不存在的片段。
有没有很好的方法来引用用EventListFragment mFragment = EventListFragment.newInstance(dateOffset);
创建的片段?或者我该如何从我的活动中刷新ViewPager中的片段(从选项菜单中精确)?
答案 0 :(得分:5)
我设法解决了这个问题。诀窍是在Activity中创建一个引用列表,而不是PagerAdapter。它是这样的:
List<WeakReference<EventListFragment>> fragList = new ArrayList<WeakReference<EventListFragment>>();
@Override
public void onAttachFragment (Fragment fragment) {
Log.i(TAG, "onAttachFragment: "+fragment);
if(fragment.getClass()==EventListFragment.class){
fragList.add(new WeakReference<EventListFragment>((EventListFragment)fragment));
}
}
public EventListFragment getFragmentByPosition(int position) {
EventListFragment ret = null;
for(WeakReference<EventListFragment> ref : fragList) {
EventListFragment f = ref.get();
if(f != null) {
if(f.getPosition()==position){
ret = f;
}
} else { //delete from list
fragList.remove(f);
}
}
return ret;
}
当然你的片段必须实现getPosition()
函数,但无论如何我需要这样的东西,所以这不是问题。
感谢Alex Lockwood对WeakReference
提出的建议!
答案 1 :(得分:3)
两件事:
在活动的onCreate
方法中(或初始化ViewPager的任何位置)添加以下行:
mPager.setOffscreenPageLimit(NUM_ITEMS-1);
这会将额外的屏幕外页面保留在内存中(即防止它们被破坏),即使它们当前没有显示在屏幕上也是如此。
您可以考虑实施HashMap
,使其保留WeakReference<Fragment>
而不是Fragment
s。请注意,这需要您更改getFragment
方法,如下所示:
WeakReference<Fragment> weakRef = mPageReferenceMap.get(position);
return (weakRef != null) ? weakRef.get() : null;
这与你的问题无关......这只是我注意到的事情,我想我会引起你的注意。将WeakReferences
保留到Fragment
将允许您利用垃圾收集器为您确定可达性的能力,因此您不必自己执行此操作。