10

我在 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 中的片段(准确地说是从选项菜单)?

4

2 回答 2

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()功能,但无论如何我都需要这样的东西,所以这不是问题。

感谢亚历克斯洛克伍德的建议WeakReference

于 2012-05-14T18:30:37.430 回答
4

两件事情:

  1. onCreate在 Activity 的方法(或初始化 ViewPager 的任何位置)中添加以下行:

    mPager.setOffscreenPageLimit(NUM_ITEMS-1);
    

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

  2. 您可能会考虑实施 yourHashMap以便它拥有WeakReference<Fragment>s 而不是Fragments 本身。请注意,这将要求您getFragment按如下方式更改您的方法:

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

    这与您的问题无关......这只是我注意到并认为我会引起您注意的事情。保持WeakReferencesFragment的 s 将允许你利用垃圾收集器的能力来确定你的可达性,所以你不必自己做。

于 2012-05-13T19:10:30.503 回答