2011-05-23 52 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

相关问题