Android 是否有方法获取活动中所有当前活动片段的引用?

Android 是否有方法获取活动中所有当前活动片段的引用?,android,android-fragments,android-3.0-honeycomb,Android,Android Fragments,Android 3.0 Honeycomb,我还没有找到一种简单的方法来获取活动中所有当前活动(可见,当前处于恢复状态)的片段。在我的活动中是否可以不进行定制记账?FragmentManager似乎不支持此功能。看起来API当前缺少了“getFragments”之类的方法。 然而,使用类活动的事件“onAttachFragment”,应该可以很容易地完成您想要的任务。我会这样做: List<WeakReference<Fragment>> fragList = new ArrayList<WeakRefere

我还没有找到一种简单的方法来获取活动中所有当前活动(可见,当前处于恢复状态)的片段。在我的活动中是否可以不进行定制记账?FragmentManager似乎不支持此功能。

看起来API当前缺少了“getFragments”之类的方法。
然而,使用类活动的事件“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;
}
List fragList=new ArrayList();
@凌驾
公共碎片(碎片碎片){
添加(新的WeakReference(片段));
}
公共列表getActiveFragments(){
ArrayList ret=新的ArrayList();
对于(WeakReference ref:fragList){
片段f=ref.get();
如果(f!=null){
如果(f.isVisible()){
再加上(f);
}
}
}
返回ret;
}
如果没有现成的方法从对象读取状态(示例中为isActive()),我将覆盖onResume和onPause以设置标志(可能只是bool字段)。

这已经是一些自己的簿记,但考虑到您想要实现的非常具体的目标(状态相关列表),我认为仍然非常有限。

另一种方法是在将片段添加到活动中时,在片段上添加标记

例如,如果动态添加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
然后,如果以后需要取回所有片段,可以执行以下操作:

for (int i = 0; i < NUM_FRAGMENTS; i++) {
     String tag = SOME_CUSTOM_PREFIX + i;
     fragmentList.add((MyFragment) fragmentManager.findFragmentByTag(tag));
}
for(int i=0;i
如果您使用Android支持库,则可以调用hidden
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;
}
public List getVisibleFragments(){
列出所有片段=getSupportFragmentManager().getFragments();
if(allFragments==null | | allFragments.isEmpty()){
返回集合。emptyList();
}
List visibleFragments=new ArrayList();
for(片段片段:所有片段){
if(fragment.isVisible()){
visibleFragments.add(片段);
}
}
返回可见片段;
}
我解决了这个问题:

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;

}
public ArrayList getAllFragments(){
ArrayList lista=新的ArrayList();
对于(片段片段:getSupportFragmentManager().getFragments()){
试一试{
fragment.getTag();
添加(片段);
}捕获(NullPointerException e){
}
}
返回列表a;
}

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();
/**
*获取已添加到片段管理器的所有片段的列表。
*
*@返回所有片段的列表,如果没有,则返回null。
*@隐藏
*/
公共摘要列表getFragments();

常规的
android.app.FragmentManager
根本没有这个方法,但是如果真的需要,您可以通过反射获取字段
mActive
来访问同一个对象(注意:从API 26开始,它的类型是
SparseArray
,而不是
List
)。自担风险使用:)

我们可以使用一些不规则但合法的方法

    ArrayList<Fragment> getActiveFragments() {
        Fragment f;
        final ArrayList<Fragment> fragments = new ArrayList<>();
        int i = 0;
        try {
            while ((f = getFragmentManager().getFragment(new Intent().putExtra("anyvalue", i++).getExtras(), "anyvalue")) != null) {
                fragments.add(f);
            }
        } catch (IllegalStateException ex) {

        }
        return fragments;
    }
ArrayList getActiveFragments(){
片段f;
最终ArrayList片段=新ArrayList();
int i=0;
试一试{
while((f=getFragmentManager().getFragment(new Intent().putExtra(“anyvalue”,i++).getExtras(),“anyvalue”))!=null){
加入(f);
}
}捕获(非法状态例外){
}
返回碎片;
}

这是Kotlin中的递归解决方案。给定活动的最顶端片段,返回所有子片段

fun recursiveGetFragments(父对象:列表):列表{
val result=parents.toMutableList()
for(根于父对象){
if(root.isVisible){
addAll(recursiveGetFragments(root.childFragmentManager.fragments))
}
}
返回结果
}
它被用作:

val fragmentList=recursiveGetFragments(supportFragmentManager.fragments)

Hmm,如果没有对添加到片段列表中的实际片段的引用,WeakReference ref是否会变为null?这对于我来说非常有用。PS我有一行:如果(f!=null&&f.isVisible()){ret.add(f);}否,ref本身不会变为null,只有get()会在活动被垃圾收集时返回null。因此,将get()赋值给变量f,然后检查它是否为null是安全的。实际上,支持库公开了一个
getFragments()
方法,但不应该使用它。它用
@hide
标记,不应包含在支持库jar中。它不应该被视为导出API的一部分。如果片段被分离,那么片段引用列表不应该被更新吗?否则,您可能会在该列表中有一些片段,这些片段已经消失很久了(或者至少不再出现在屏幕上)。它用
@hide
标记,不应包含在支持库jar中。它不应该被视为导出API的一部分。如果您使用的是支持库,并且知道其中的内容,那么您可以调用任何想要的方法。可能发生的最糟糕的事情是,在切换到库的较新版本后,您将得到编译错误。@Michael对于此方法,我想为将来的观众指出一件重要的事情