Программно вернуться к предыдущему фрагменту в стопке

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

private void animateToFragment(Fragment newFragment, String tag) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.fragment_container, newFragment, tag); ft.addToBackStack(null); ft.commit(); } 

Каков наилучший способ вернуться к предыдущему фрагменту, который был видимым?

Я обнаружил , что функция кнопки «Триггер» при нажатии кнопки на Android, но я думаю, что симуляция события «назад» не является правильным способом (и я не могу заставить его работать):

 dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); 

Calling finish() просто закрывает активность, которая мне не интересна.

Есть ли лучший способ сделать это?

Solutions Collecting From Web of "Программно вернуться к предыдущему фрагменту в стопке"

Посмотрите на getFragmentManager().popBackStack() (их можно выбрать)

http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack ()

Чтобы рассказать о других полученных ответах, это мое решение (помещено в действие):

 @Override public void onBackPressed(){ FragmentManager fm = getFragmentManager(); if (fm.getBackStackEntryCount() > 0) { Log.i("MainActivity", "popping backstack"); fm.popBackStack(); } else { Log.i("MainActivity", "nothing on backstack, calling super"); super.onBackPressed(); } } 

Когда мы обновляем / добавляем фрагменты,

Должен включать .addToBackStack ().

 getSupportFragmentManager().beginTransaction() .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null). .addToBackStack(null) .commit(); 

После этого, если мы дадим getFragments.popBackStackImmediate (), вернем true, если мы добавим / обновим фрагменты и вернемся к текущему экрану.

replace() делает 2 вещи:

  1. Удалите добавленный фрагмент (A) из контейнера (C), который вы указали
  2. Добавить новый фрагмент (B) в тот же контейнер

Эти 2 операции – это то, что сохраняется как запись / транзакция Backstack. Обратите внимание, что фрагмент A остается в created состоянии, и его представление уничтожено.

Теперь popBackStack() отменяет вашу последнюю транзакцию, добавленную в BackStack.

В этом случае это будет 2 шага:

  1. Удалить B из C
  2. Добавить A в C

После этого фрагмент B detached , и если вы не будете ссылаться на него, это будет собирать мусор.

Чтобы ответить на первую часть вашего вопроса, нет onCreate() , потому что FragmentB остался в created состоянии. И ответ на вторую часть вопроса немного длиннее.

Во-первых, важно понимать, что вы фактически не добавляете Fragments в Backstack, вы добавляете FragmentTransactions . Поэтому, когда вы думаете, что вы «замените фрагментом B, добавив фрагмент A в задний стек», вы фактически добавите всю эту операцию в стопку – это замена A на B. Эта замена состоит из двух действий – удалите A и добавьте B ,

Затем, следующий шаг – всплытие транзакции, которая содержит эту замену. Таким образом, вы не выходите из FragmentA, вы меняете «удалить A, добавьте B», который обратный – «удалить B, добавить A».

И тогда последний шаг должен быть яснее – нет B, о котором знает FragmentManager, поэтому, добавив его, заменив A на B на последнем шаге, B должен пройти его ранние методы жизненного цикла – onAttach() и onCreate() .

Приведенный ниже код иллюстрирует, что происходит.

 FragmentManager fm = getFragmentManager(); FragmentA fragmentA = new FragmentA(); FragmentB fragmentB = new FragmentB(); // 1. Show A fm.beginTransaction() .add(fragmentA, R.id.container) .commit(); // 2. Replace A with B // FragmentManager keeps reference to fragmentA; // it stays attached and created; fragmentB goes // through lifecycle methods onAttach(), onCreate() // and so on. fm.beginTransaction() .replace(fragmentB, R.id.container) .addToBackstack(null) .commit(); // 2'. Alternative to replace() method fm.beginTransaction() .remove(fragmentA) .add(fragmentB, R.id.container) .addToBackstack(null) .commit(); // 3. Reverse (2); Result - A is visible // What happens: // 1) fragmentB is removed from container, it is detached now; // FragmentManager doesn't keep reference to it anymore // 2) Instance of FragmentA is placed back in the container // Now your Backstack is empty, FragmentManager is aware only // of FragmentA instance fm.popBackStack(); // 4. Show B // Since fragmentB was detached, it goes through its early // lifecycle methods: onAttach() and onCreate(). fm.beginTransaction() .replace(fragmentB, R.id.container) .addToBackstack(null) .commit(); 

Добавьте эти строки в метод onBackPressed (). Метод popBackStackImmediate () вернет вас к предыдущему фрагменту, если у вас есть фрагмент на back stack `

 if(getFragmentManager().getBackStackEntryCount() > 0){ getFragmentManager().popBackStackImmediate(); } else{ super.onBackPressed(); } 

`

Программно вернуться к предыдущему фрагменту, используя следующий код.

 if ( getFragmentManager().getBackStackEntryCount() > 0) { getFragmentManager().popBackStack(); return; } super.onBackPressed();