2011-05-23 54 views

回答

106

看起來API目前錯過了像「getFragments」這樣的方法。
但是,使用Activity類的onAttachFragment事件應該很容易做到你想要的。我會做這樣的事情:

List<WeakReference<Fragment>> fragList = new ArrayList<WeakReference<Fragment>>(); 
@Override 
public void onAttachFragment (Fragment fragment) { 
    fragList.add(new WeakReference(fragment)); 
} 

public List<Fragment> getActiveFragments() { 
    ArrayList<Fragment> ret = new ArrayList<Fragment>(); 
    for(WeakReference<Fragment> ref : fragList) { 
     Fragment f = ref.get(); 
     if(f != null) { 
      if(f.isVisible()) { 
       ret.add(f); 
      } 
     } 
    } 
    return ret; 
} 

如果沒有從(在本例中isActive())的對象讀取狀態準備好方法,我會覆蓋的onResume和的onPause設置標誌(可能只是一個布爾字段)。
這已經是一些自己的簿記了,但在我看來,考慮到你想實現的具體目標(狀態依賴列表),它仍然非常有限。

+2

嗯,如果沒有對添加到onAttachFragment列表中的實際片段的引用,那麼WeakReference ref是否爲null? – 2011-08-11 22:23:36

+2

這對我的目的非常有用。 PS我有行:if(f!= null && f.isVisible()){ \t \t \t \t ret.add(f); \t \t \t} – 2011-08-12 02:13:11

+0

不,ref本身不會變爲null,如果活動被垃圾收集,get()將返回null。因此,將get()分配給變量f然後檢查它是否是安全的。 – 2011-08-13 03:03:40

2

另一種方法是在將標籤添加到活動時將標籤放在碎片上。

舉例來說,如果你動態地添加4個片段,你可以將它們添加喜歡:

for (int i = 0; i < NUM_FRAGMENTS; i++){ 
    MyFragment fragment = new Fragment(i); 
    fragmentTransaction.add(R.id.containerId, fragment, SOME_CUSTOM_PREFIX + i).commit() 
} 

然後,如果你需要得到所有的碎片回來以後,你可以這樣做:

for (int i = 0; i < NUM_FRAGMENTS; i++) { 
    String tag = SOME_CUSTOM_PREFIX + i; 
    fragmentList.add((MyFragment) fragmentManager.findFragmentByTag(tag)); 
} 
12

如果你使用Android支持庫,然後就可以調用隱藏FragmentManager.getFragments()方法:

public List<Fragment> getVisibleFragments() { 
    List<Fragment> allFragments = getSupportFragmentManager().getFragments(); 
    if (allFragments == null || allFragments.isEmpty()) { 
     return Collections.emptyList(); 
    } 

    List<Fragment> visibleFragments = new ArrayList<Fragment>(); 
    for (Fragment fragment : allFragments) { 
     if (fragment.isVisible()) { 
      visibleFragments.add(fragment); 
     } 
    } 
    return visibleFragments; 
} 
+1

我們不應該使用這種方法。它用'@ hide'標記,不應該包含在支持庫jar中。它不應被視爲導出的API的一部分。 – 2014-03-25 06:44:14

+1

如果您正在使用支持庫並瞭解內部內容,則可以調用所需的任何方法。可能發生的最糟糕的事情是,在切換到較新版本的庫之後,會出現編譯錯誤。 – Michael 2014-03-25 09:10:03

+9

@Michael我希望爲未來的觀衆提供這種方法的一個重要事項(它看起來像你已經在這裏討論過)是它返回內部片段列表,而不是它的副本。所以不要修改你回來的列表;根據返回的響應實例化一個新的List,並修改*那一個。否則,您將花費整整一天來調試間歇性的IndexOutOfBoundsException。 :) – kcoppock 2014-05-03 01:11:49

0

我解決這個:

public ArrayList<Fragment> getAllFragments() { 
    ArrayList<Fragment> lista = new ArrayList<Fragment>(); 

    for (Fragment fragment : getSupportFragmentManager().getFragments()) { 
     try { 
      fragment.getTag(); 
      lista.add(fragment); 
     } catch (NullPointerException e) { 

     } 
    } 

    return lista; 

} 
+0

我正在實現類似於這個的東西,我得到一個NPE該活動被重新創建,並調用fragment.getTag()。你知道爲什麼片段是空的嗎? – Clocker 2014-11-14 15:11:40

+0

對不起,但沒有。只爲我工作。 – 2014-12-11 17:17:09

1

android.support.v4.app.FragmentManager有一個名爲getFragments()這不正是你需要的方法,但它從來沒有訪問。突然,雖然,但是,我不確定這是否意圖是因爲它仍然被標記爲隱藏。

/** 
* Get a list of all fragments that have been added to the fragment manager. 
* 
* @return The list of all fragments or null if none. 
* @hide 
*/ 
public abstract List<Fragment> getFragments(); 

常規android.app.FragmentManager沒有這個方法可言,但如果真的需要,可以通過反射得到場mActive訪問同一個對象(小心有:首先是API 26,它的類型是一個SparseArray而不是List)。請自行承擔風險:)

+1

該方法是公開的,但[它有一個錯誤](https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner% 20Summary%20Stars&groupby =&sort = -id&id = 226196) – 2016-11-16 15:44:53

+0

迭代過程中的空檢查修復了這個錯誤。 – 0101100101 2016-11-22 08:50:11

+0

它可用於android.app.FragmentManager! – 2016-12-05 10:58:04

相關問題