Is there a way to get references for all currently active fragments in an Activity?

Solution 1:

Looks like the API currently misses a method like "getFragments".
However using the event "onAttachFragment" of class Activity it should be quite easy to do what you want. I would do something like:

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;
}

In case there's no ready method to read the state from the object (isActive() in the example), I would override onResume and onPause to set a flag (could be just a bool field).
That's already some own bookkeeping, but still very limited in my opinion considering the quite specific goal you want to achieve (status dependent list).

Solution 2:

If you use Android Support Library, then you can call hidden FragmentManager.getFragments() method:

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;
}

Solution 3:

Another way to do this would be to put tags on your fragments when you add them to the activity.

For example, if you dynamically add 4 fragments, you can add them like:

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

Then, if you need to get all the fragments back later, you can do:

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

Solution 4:

I resolved with this:

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;

}

Solution 5:

android.support.v4.app.FragmentManager has a method called getFragments() which does exactly what you need, but it was never accessible. Suddenly, though, it is, but I'm not sure if that's intended because it's still marked as hidden.

/**
 * 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();

The regular android.app.FragmentManager doesn't have this method at all, but if really needed, you can access the same object by getting the field mActive via reflection (be careful there: starting with API 26, its type is a SparseArray instead of List). Use at own risk :)