10

ViewPager 内で Fragments を参照する際に問題があります。私のアクティビティから、指定された位置(現在表示されているフラグメントなど)でフラグメントを更新したいので、それをやりたいと思います。

現在、私は次のようなものを持っています:

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()ため、null 参照が残っていることです。破棄されたフラグメントへの参照をクリアするために使用destroyItem()しない場合...まあ、存在しないフラグメントを参照します。

で作成されたフラグメントを参照する良い方法はありますEventListFragment mFragment = EventListFragment.newInstance(dateOffset);か? または、アクティビティから (正確にはオプション メニューから) ViewPager 内のフラグメントを更新するにはどうすればよいですか?

4

2 に答える 2

5

私はそれを解決することができました。コツは、PagerAdapter ではなく、Activity 内に参照リストを作成することでした。こんなふうになります:

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

2つのこと:

  1. Activity のonCreateメソッド (または ViewPager を初期化する場所)に次の行を追加します。

    mPager.setOffscreenPageLimit(NUM_ITEMS-1);
    

    これにより、現在画面に表示されていない場合でも、追加のオフスクリーン ページがメモリに保持されます (つまり、ページが破棄されるのを防ぎます)。

  2. s 自体の代わりに s をHashMap保持するようにyour を実装することを検討してください。これには、次のようにメソッドを変更する必要があることに注意してください。WeakReference<Fragment>FragmentgetFragment

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

    これはあなたの問題とは何の関係もありません...それは私が気づいたことであり、あなたの注意を喚起したいと思っただけです. s を維持WeakReferencesするFragmentことで、ガベージ コレクターの機能を利用して到達可能性を判断できるため、自分で行う必要はありません。

于 2012-05-13T19:10:30.503 に答える