Есть ли способ получить ссылки на все активные в данный момент фрагменты в Activity? - PullRequest
60 голосов
/ 23 мая 2011

Я не нашел простого способа получить все активные в данный момент (видимые, в настоящее время в возобновленном состоянии) фрагменты в действии.Возможно ли это в моей деятельности?Похоже, FragmentManager не поддерживает эту функцию.

Ответы [ 6 ]

109 голосов
/ 12 августа 2011

Похоже, что API в настоящее время пропускает метод типа "getFragments".
Однако, используя событие «onAttachFragment» класса Activity, должно быть довольно легко делать то, что вы хотите. Я бы сделал что-то вроде:

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, чтобы установить флаг (это может быть просто поле bool).
Это уже некоторая собственная бухгалтерия, но, на мой взгляд, она все еще очень ограничена, учитывая вполне конкретную цель, которую вы хотите достичь (список, зависящий от статуса).

14 голосов
/ 04 декабря 2013

Если вы используете библиотеку поддержки 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;
}
2 голосов
/ 04 февраля 2013

Еще один способ сделать это - добавить теги к фрагментам при добавлении их в упражнение.

Например, если вы динамически добавляете 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));
}
1 голос
/ 30 августа 2016

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 голос
/ 20 июля 2014

Я решил с этим:

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 голосов
/ 21 марта 2019

мы можем использовать нерегулярный, но законный метод

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