web-dev-qa-db-fra.com

Existe-t-il un moyen d'obtenir des références pour tous les fragments actuellement actifs dans une activité?

Je n'ai pas trouvé de moyen simple d'obtenir tous les fragments actuellement actifs (visibles, actuellement en état de reprise) dans une activité. Est-il possible sans comptabilité personnalisée dans mon activité? Il semble que FragmentManager ne supporte pas cette fonctionnalité.

60

Il semble que l'API manque actuellement une méthode comme "getFragments".
Cependant, en utilisant l'événement "onAttachFragment" de l'activité de classe, il devrait être assez facile de faire ce que vous voulez. Je ferais quelque chose comme:

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

Dans le cas où il n'y a pas de méthode prête à lire l'état de l'objet (isActive () dans l'exemple), je remplacerais onResume et onPause pour définir un indicateur (pourrait être juste un champ booléen).
C'est déjà une comptabilité propre, mais encore très limitée à mon avis compte tenu de l'objectif assez spécifique que vous souhaitez atteindre (liste dépendante du statut).

109
didi_X8

Si vous utilisez Android Support Library, vous pouvez appeler la méthode FragmentManager.getFragments() cachée:

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

Une autre façon de procéder serait de mettre des balises sur vos fragments lorsque vous les ajoutez à l'activité.

Par exemple, si vous ajoutez dynamiquement 4 fragments, vous pouvez les ajouter comme:

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

Ensuite, si vous devez récupérer tous les fragments plus tard, vous pouvez faire:

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

Android.support.v4.app.FragmentManager A une méthode appelée getFragments() qui fait exactement ce dont vous avez besoin, mais elle n'a jamais été accessible. Du coup, c'est le cas, mais je ne sais pas si c'est prévu car il est toujours marqué comme caché.

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

Le Android.app.FragmentManager Habituel n'a pas du tout cette méthode, mais si vous en avez vraiment besoin, vous pouvez accéder au même objet en récupérant le champ mActive via la réflexion (attention là: à partir de l'API 26, son type est un SparseArray au lieu de List). Utilisez à vos risques et périls :)

1
0101100101

J'ai résolu ceci:

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;

}

nous pouvons utiliser une méthode irrégulière mais légale

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