Android - addToBackStack() не работает?

Это функция, отвечающая за добавление фрагментов в задний стек:

public void populateContent(File f)
{

    ContentFragment cf = new ContentFragment(ctx, ac, this);
    FragmentTransaction transaction = ac.getSupportFragmentManager().beginTransaction();;
    cf.updateView(f);

    transaction.replace(R.id.contentFragment, cf);

    transaction.addToBackStack(null);

    transaction.commit();

}

Когда я нажимаю кнопку «Назад», последний фрагмент не загружается (ничего не происходит).

Любая идея, что может быть причиной этого?

Изменить: журнал FragmentManager.

http://pastebin.com/mYnVdkLG

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


person Tool    schedule 11.02.2013    source источник
comment
я думаю, вы должны сначала добавить tobackStack(), а затем заменить фрагмент...   -  person user1969053    schedule 11.02.2013
comment
Посмотрите этот ответ: stackoverflow.com/a/14030872/1484779   -  person jlopez    schedule 11.02.2013
comment
Я попробовал это и добавил в свою активность следующий метод, который не сработал. pastebin.com/aezQD48p   -  person Tool    schedule 11.02.2013
comment
Может ли проблема быть в том, что я использую SupportManager вместо Manager? Я вижу, что вопрос, который вы связали, связан с ChildFragmentManager - мой SupportManager.   -  person Tool    schedule 11.02.2013
comment
На самом деле addToBackStack(null) не будет работать с Fragment и AppCompatActivity. Однако он работает с v4 Fragment и AppCompatActivity (проверено)   -  person deadfish    schedule 24.02.2016


Ответы (3)


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

Вы действительно заменяете два фрагмента? Если вы этого не сделаете, то транзакции для отмены не будет. Также ваш первый Fragment добавлен из XML? Менеджер не будет знать об этом фрагменте, и вам может понадобиться добавить первый Fragment тоже с помощью транзакции.

Будьте осторожны, проверяя if (savedInstanceState == null) performFirstTransaction(), иначе вы в конечном итоге добавите свой первый Fragment дважды.

Хорошая идея — использовать enableDebugLogging в FragmentManager. Это расскажет вам о том, о каких фрагментах знает менеджер.

См. это: http://developer.android.com/reference/android/app/FragmentManager.html#enableDebugLogging(boolean)

В качестве примечания НЕ рекомендуется использовать пользовательский конструктор для вашего файла Fragment. Это потому, что если ваше приложение будет убито и повторно создано ОС, оно вызовет пустой конструктор.

Вы должны использовать статический метод, такой как ContentFragment.getInstance(<params>), чтобы создать файл Fragment.

Дополнительные сведения см. по адресу: http://developer.android.com/reference/android/app/Fragment.html в разделе «Обзор классов».

Я надеюсь, что мой ответ немного поможет вам найти проблему.

person dnkoutso    schedule 11.02.2013
comment
Кроме того, у меня нет собственного конструктора для моего фрагмента — я его не менял. Однако у меня есть метод во фрагменте, который служит средством обновления представления. - person Tool; 11.02.2013
comment
Хорошо, я выложил ссылку на лог из менеджера. - person Tool; 11.02.2013

Кажется, что вызова addToBackStack() для транзакции фрагмента недостаточно, мы должны обрабатывать всплывающее окно заднего стека при нажатии кнопки «Назад» самостоятельно. Я добавил это в свою деятельность, и это сработало, как и ожидалось:

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}
person Tony Vu    schedule 28.10.2014
comment
Это работает, но не воспроизводит анимацию. РЕДАКТИРОВАТЬ: Если вы хотите воспроизвести анимацию в popbackstack, добавьте два дополнительных параметра при вызове setCustomAnimation. См. здесь. - person Nathan; 13.06.2015
comment
Это прекрасно работает. Удивительно, что нам приходится справляться с этим самим, потому что, я думаю, в документации сказано, что это произойдет автоматически. - person Ankit; 15.09.2015
comment
если это где-то задокументировано? - person Defuera; 12.10.2015
comment
Раньше работал без него, но недавно у меня была такая же проблема, и это решило проблему... - person Warpzit; 14.11.2015
comment
Вам не нужно этого делать, если ваша активность распространяется с FragmentActivity и транзакции добавляются с помощью getSupportFragmentManager. getSupportFragmentManager().beginTransaction().addToBackStack() - person vdua; 06.02.2016
comment
Вы только что избавили меня от головной боли! - person oxyt; 29.03.2016

Я добавлял, а не заменял, но мне пришлось вызывать addToBackStack(null) перед add(), а не после, для фрагмента, который закроется, а не для фрагмента, который останется открытым.

В классе А (открылся первым)

FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.layout_a, f, Constants.FRAGMENT_KEY);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();

В классе В (открыт классом А)

FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
ft.add(R.id.layout_b, f, Constants.FRAGMENT_KEY);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
person Susanne Siverland    schedule 19.02.2015
comment
addToBackStack при выполнении добавления/замены фрагмента сделал это для меня. - person Clocker; 24.11.2015
comment
вызовите addToBackStack(null) перед add(), а не после Это именно то, в чем была моя проблема. Вы избавили меня от тонны головной боли. Спасибо! - person Gautham C.; 29.03.2017