2012-05-13 14 views
9

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

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

答えて

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()機能を実装する必要がありますが、私はとにかくこのような何かを必要とするので、それは問題ではありませんでした。

ありがとうございましたAlex Lockwoodさんのご提案ありWeakReference

+0

私は決勝を終え、戻って来て、あなたが仕事をしているかどうかを見てみることにしました。私が助けてくれることを嬉しく思います(それは主要な問題ではない:P)。 –

+0

質問:fragList.remove()コールに、フラグメントではなく弱参照を渡すべきではありませんか? – gcl1

+0

@Michael:私はこのようなアプローチを使い始めました。しかし、fragListには弱い参照が含まれているので、必要な場合でも、エントリはガベージコレクションの対象になるようです。私はgetFragmentByPosition()メソッドがnullを返すことがあることを見てきました。だから私はそれが起こっていると思います。どのようにそれを回避するための任意のアイデアですか?ありがとう。 – gcl1

3

2つのこと:これは、メモリ内の追加のオフスクリーンのページを維持します

mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

  1. は、あなたの活動のonCreateメソッド(またはどこでもあなたのViewPagerを初期化)に次の行を追加します。現在画面に表示されていないときでも、それらが破壊されるのを防止します。

  2. Fragmentの代わりにWeakReference<Fragment>を保持するようにHashMapを実装することを検討することがあります。これは次のようにあなたのgetFragment方法を変更することが必要になることに注意してください:

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

    これはあなたの問題とは何の関係もありません...それは私が気づいたと私はあなたの注意にもたらすだろうと思っただけで何かをです。 WeakReferencesFragmentに保存すると、可読性を判断するガベージコレクタの能力を活用できるようになります。したがって、自分で行う必要はありません。

+0

2. =>それは私の問題を解決することはできませんが、おそらくリークを防ぐための良い考えです、ありがとう。そして、1 =>私は7ページを持っていますが、将来的には、それらをすべて同時にメモリに保存してもよろしいですか? –

+0

ええと...明らかに、あなたが記憶に残っている「断片」が少なくて済むのは明らかです。 'Activity'の中で' Fragment'sにアクセスしたいのであれば(実際に 'Fragment'sのページに切り替える必要はありません)、それらをすべてメモリに保持しておきたいのであれば、修正は難しいでしょう。 'ViewPager'ソースコードを掘り下げ、' Fragment'ライフサイクルをどのように処理するのかを見る必要があります。私はこれを行う方法を知らないが、私は時間があればそれを調べるだろう。 –

+0

私は謙虚にお勧めしますが、あなたがオフスクリーンである間にフラグメントから取得する必要があるものがあれば、それをフラグメントに与えるべきではないかもしれません。それをServiceまたはContentProviderに入れ、あなたのフラグメントをそのクライアントにすることを検討してください。 – Sparky