Android удалить фрагмент и вид из BackStack - PullRequest
33 голосов
/ 09 февраля 2012

enter image description here

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

У меня есть следующий метод FragmentHelper:

public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx)
    {
        // Create new fragment and transaction
        FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction();
        transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(container, fragment);

        if(addToBackStack)
            transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }

Втранзакция от B до CI устанавливает логическое addToBackStack как ложное, так что transaction.addToBackStack(null); не вызывается.Это снова работает хорошо, но после этого моя проблема начинается.

Когда пользователь нажимает на C и возвращается к AI, он все еще может видеть раздутый вид C под видом A.

Любойпомощь будет оценена.Я надеюсь, что моя диаграмма помогает сделать это простым.

Ответы [ 6 ]

21 голосов
/ 29 декабря 2012

Я решил это .. в пределах строки ...

getFragmentManager().popBackStack();

или

getSupportFragmentManager().popBackStack()

это работает, когда вы добавляете фрагменты и сохраняете backstack (не заменяя).

6 голосов
/ 27 июня 2014

f1 -> f2

Fragment2 f2 = new Fragment2();
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit();

ничего необычного здесь.Чем во фрагменте f2 этот код приводит вас к фрагменту f3.

f2 -> f3

Fragment3 f3 = new Fragment3();
getActivity().getSupportFragmentManager().popBackStack();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();

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

Упомянутая альтернатива будет:

final FragmentActivity activity = getActivity();
activity.getSupportFragmentManager().popBackStackImmediate();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();

Здесь на самом деле будет краткий переход к f1, прежде чем перейти к f3,так что небольшой сбой.

Это на самом деле все, что вам нужно сделать, и этот ответ также может вам помочь.

1 голос
/ 20 февраля 2012

Пара способов справиться с этим:

  1. У меня был похожий поток в моем приложении, и я решил его путем замены фрагмента входа в систему AlertDialog, который запускается из основного действия. Таким образом, в вашем случае фрагмент A отображается на экране, и если основной вид деятельности считает необходимым показать диалог входа в систему, он показывает AlertDialog. Это сработало для меня.

  2. Когда фрагмент A включен, он может проверить, присутствует ли фрагмент C, запрашивая FragmentManager. Если он существует, удалите его.

0 голосов
/ 15 января 2018

Привет, я просто хотел поделиться элегантным решением, которое нашел.

public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) {
final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1;

fragmentManager.beginTransaction()
    .replace(R.id.content, fragment, tag)
    .addToBackStack(tag)
    .commit();

fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override
  public void onBackStackChanged() {
    int nowCount = fragmentManager.getBackStackEntryCount();
    if (newBackStackLength != nowCount) {
      // we don't really care if going back or forward. we already performed the logic here.
      fragmentManager.removeOnBackStackChangedListener(this);

      if ( newBackStackLength > nowCount ) { // user pressed back
        fragmentManager.popBackStackImmediate();
      }
    }
  }
});
}

Источник с объясненной логикой .

0 голосов
/ 09 августа 2016

Шаг 1: Когда вы во Фрагменте A и хотите открыть Фрагмент B

getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentB(), FragmentB.class.getName()
.addToBackStack(null)
.commit();

Шаг 2: Когда вы во Фрагменте B и хотите открыть Фрагмент C

getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentC(), FragmentC.class.getName()
.disallowAddToBackStack() // << this to make Fragment B, not included in the backstack
.commit();

Шаг 3. Когда вы во фрагменте C и нажмете кнопку возврата устройства или getFragmentManager().popBackStack();, вы откроете фрагмент A.

PS: в Activity используйте это getSupportFragmentManager(). Если вы во Фрагменте, используйте getFragmentManager()

0 голосов
/ 11 февраля 2012

Не сообщая FM, что вы хотите, чтобы переход от B к C был добавлен в backStack, означает, что при обратном ударе FM не имеет записи о добавлении C, поэтому он не удаляет его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...