在ViewPager中引用片段

我在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);创build的片段EventListFragment mFragment = EventListFragment.newInstance(dateOffset); ? 或者我该怎么做,以从我的活动(从选项菜单中精确地)刷新ViewPager中的片段?

Solutions Collecting From Web of "在ViewPager中引用片段"

我设法解决它。 诀窍是在Activity中创build引用列表,而不是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的build议!

两件事情:

  1. 在你的Activity的onCreate方法中(或你初始化ViewPager的地方)添加下面这行:

     mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

    这将使附加的离屏页面保留在内存中(即防止它们被破坏),即使当前没有显示在屏幕上。

  2. 你可能会考虑实现你的HashMap ,使它拥有WeakReference<Fragment>而不是Fragment本身。 请注意,这将需要您更改您的getFragment方法,如下所示:

     WeakReference<Fragment> weakRef = mPageReferenceMap.get(position); return (weakRef != null) ? weakRef.get() : null; 

    这与你的问题没有任何关系……这只是我注意到的事情,我想会引起你的注意。 保持WeakReferences到你的Fragment s将允许你利用垃圾收集器的能力来确定你的可达性,所以你不必自己动手。