Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Получить последний фрагмент в бэкстеке

Автор вопроса: Leem.finОтветов: 12

Как я могу получить последний экземпляр фрагмента, добавленный в backstack (если я не знаю тег и идентификатор фрагмента)?

FragmentManager fragManager = activity.getSupportFragmentManager();
FragmentTransaction fragTransacion = fragMgr.beginTransaction();

/****After add , replace fragments
  (some of the fragments are add to backstack , some are not)***/

//HERE, How can I get the latest added fragment from backstack ??

androidandroid-fragmentsback-stack

Ответы

Ответ 1 · рейтинг 158 · Deepak Goel

Вы можете использовать метод getName() для FragmentManager.BackStackEntry, который был представлен на уровне API 14. Этот метод вернет тег, который вы использовали, когда добавляли фрагмент в стопку с помощью addTobackStack(tag).

int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1
FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment fragment = getFragmentManager().findFragmentByTag(tag);

Вам нужно убедиться, что вы добавили фрагмент в стопку следующим образом:

fragmentTransaction.addToBackStack(tag);

Ответ 2 · рейтинг 49 · ashakirov

FragmentManager.findFragmentById(fragmentsContainerId)

функция возвращает ссылку на начало Fragment в стопке. Пример использования:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", fr.getClass().getSimpleName());
            }
        }
    });

Ответ 3 · рейтинг 43 · ptitvinou

Я лично пробовал многие из этих решений и в итоге получил это рабочее решение:

Добавьте этот служебный метод, который будет использоваться несколько раз ниже, чтобы получить количество фрагментов в вашем backstack:

protected int getFragmentCount() {
    return getSupportFragmentManager().getBackStackEntryCount();
}

Затем, когда вы добавляете/заменяете свой фрагмент с помощью метода FragmentTransaction, сгенерируйте уникальный тег для вашего фрагмента (например, используя количество фрагментов в вашем стеке):

getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount()));

Наконец, вы можете найти любой из ваших фрагментов в вашем бэкстеке с помощью этого метода:

private Fragment getFragmentAt(int index) {
    return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null;
}

Таким образом, получить верхний фрагмент в вашем стеке можно легко, вызвав:

protected Fragment getCurrentFragment() {
    return getFragmentAt(getFragmentCount() - 1);
}

Надеюсь это поможет!

Ответ 4 · рейтинг 14 · The Finest Artist

Котлин

// In activities
activity.supportFragmentManager.fragments.lastOrNull()

// In fragments
fragment.childFragmentManager.fragments.lastOrNull()

Ответ 5 · рейтинг 11 · roghayeh hosseini

этот вспомогательный метод получает фрагмент из вершины стека:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}

Ответ 6 · рейтинг 6 · Erez

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

public Fragment getTopFragment() {
 List<Fragment> fragentList = fragmentManager.getFragments();
 Fragment top = null;
  for (int i = fragentList.size() -1; i>=0 ; i--) {
   top = (Fragment) fragentList.get(i);
     if (top != null) {
       return top;
     }
   }
 return top;
}

Ответ 7 · рейтинг 5 · Eduardo

Ответ, данный Deepak Goel, не работает для меня, потому что я всегда получаю null от entry.getName();

Что я делаю, так это устанавливаю тег для фрагмента следующим образом:

ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG);

Где ft - моя фрагментная транзакция, а FRAGMENT_TAG - тег. Затем я использую этот код для получения фрагмента:

Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG);

Ответ 8 · рейтинг 5 · Shirane85

Просто взял ответ @roghayeh hosseini (правильный) и сделал его в Котлине для тех, кто здесь в 2017 году :)

fun getTopFragment(): Fragment? {
    supportFragmentManager.run {
        return when (backStackEntryCount) {
            0 -> null
            else -> findFragmentByTag(getBackStackEntryAt(backStackEntryCount - 1).name)
        }
    }
}

* Это следует вызывать из действия.

Наслаждаться :)

Ответ 9 · рейтинг 3 · Blackbelt

вы можете использовать getBackStackEntryAt(). Чтобы узнать, сколько записей активность содержит в бэкстеке, вы можете использовать getBackStackEntryCount()

int lastFragmentCount = getBackStackEntryCount() - 1;

Ответ 10 · рейтинг 3 · Vasily Kravchenko

Похоже, что-то изменилось к лучшему, потому что код ниже у меня отлично работает, но я не нашел его в уже предоставленных ответах.

Котлин:

supportFragmentManager.fragments[supportFragmentManager.fragments.size - 1]

Ява:

getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1)

Ответ 11 · рейтинг 3 · Cosmin Vacaru

Я добавлю кое-что к Deepak Goel answer, так как многие люди, включая меня, получали нуль, используя его метод. По-видимому, чтобы заставить тег работать, когда вы добавляете фрагмент в стопку, вы должны делать это следующим образом:

getSupportFragmentManager.beginTransaction().replace(R.id.container_id,FragmentName,TAG_NAME).addToBackStack(TAG_NAME).commit();

Вам нужно добавить один и тот же тег дважды.

Я бы прокомментировал, но у меня нет репутации 50.

Ответ 12 · рейтинг 2 · Arne Evertsson

Держите свой собственный задний стек: myBackStack. Поскольку вы Add добавляете фрагмент к FragmentManager, добавьте его и к myBackStack. В onBackStackChanged() извлекается из myBackStack, когда его длина превышает getBackStackEntryCount.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы