Intereting Posts
Получение аппаратной плавающей запятой с помощью андроида NDK Set Value to Enum – Java Изменение цвета фона кнопки панели задач при нажатии Можно ли отменить предыдущий Toast, когда я хочу показать другой Toast? Как вручную установить java-библиотеки и сохранить / tmp как noexec? Как нарисовать круг с секционированным в android? Как отключить взаимодействие с пользователем, в то время как ProgressBar отображается в андроиде? Является ли iOS 7 Multipeer Connectivity совместимым с Android Wi-Fi Direct? Наложение изображения для создания учебного пособия в приложении для Android Как программно установить атрибут layout_align_parent_right кнопки в относительной компоновке? Смешивание представлений Android и GLSurfaceView Активность OnCreate называется, когда телефон идет спать Android: дочерние элементы разделяют нажатие на состояние со своим родителем, даже если duplicateParentState указан Как найти время сегодня или вчера в android Разница между foo.setVisibility (View.GONE) и parent.removeView (foo)

Как я могу сломать вещи с помощью фрагментов с помощью setRetainInstance (true) и добавить их в backstack?

Документы на setRetainInstance говорят:

Это можно использовать только с фрагментами, не входящими в задний стек.

Поэтому я начал играть с ним.

У меня есть одно действие с добавлением первого фрагмента A

FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new PackageFragment()); ft.commit 

То из этого фрагмента я запускаю метод из родительской активности, который добавляет фрагмент B в стопку

 FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content, new OrderFragment()); ft.addToBackStack(null); ft.commit(); 

Затем я создаю журнал сообщений из onCreate, onDestroy, onSaveInstanceState, onActivityCreated … и т. Д.

Я пробую две версии этого процесса. Поворот устройства на каждый фрагмент.

  1. по умолчанию

Все как и ожидалось. OnCreate, onDestroy на обрыве огней

  1. setRetainInstance (правда)

Все как и ожидалось? OnCreate, onDestroy на фрагментах не стрелять

И все, кажется, работают, пока фрагменты находятся в задней части экрана. Так почему же документы говорят, что я не должен использовать его? Каковы сценарии, в которых я могу попасть в беду?

благодаря

Solutions Collecting From Web of "Как я могу сломать вещи с помощью фрагментов с помощью setRetainInstance (true) и добавить их в backstack?"

Обновленный ответ:

Каковы сценарии, в которых я могу попасть в беду?

При добавлении Fragment в задний стек и передачи Bundle в Fragment из onSaveInstanceState() в onCreateView() при изменении конфигурации. Вызов setRetainInstance(true) установит Bundle setRetainInstance(true) null при изменении конфигурации.

(Я не уверен, что разработчик действительно попытается это сделать, поскольку использование setRetainInstance(true) делает onSaveInstanceState() вроде избыточным, но я не видел поведения, задокументированного в документах API, поэтому я написал этот ответ).

Если addToBackStack() как addToBackStack() и setRetainInstance(true) , setRetainInstance() частично изменяет вызовы метода жизненного цикла Fragment и значения параметров при изменении конфигурации по сравнению с вызовом только addToBackStack() .

В частности, в нижеприведенном тесте, рассматривая различия между вызовом только addToBackStack() и вызовом setRetainInstance(true) а также, видя, что происходит при изменении конфигурации:

Вызов addToBackStack() но не setRetainInstance(true) ;

  • onCreate() и onDestroy() .
  • Пакет, переданный из onSaveInstanceState() , принимается как параметр в onCreateView() .

Вызов как addToBackStack() и setRetainInstance(true) :

  • onCreate() и onDestroy() не вызываются. Это подтверждается документами API.
  • Пакет, переданный из onSaveInstanceState() , не получен в onCreateView() . Bundle пуст.

Тест с зарегистрированными вызовами метода и параметрами, проверенными на null:

В Управлении:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyFragment fragment; if (savedInstanceState != null) { fragment = (MyFragment) getFragmentManager().findFragmentByTag("my_fragment_tag"); } else { fragment = new MyFragment(); FragmentTransaction t = getFragmentManager().beginTransaction(); t.addToBackStack(null);//toggle this t.add(android.R.id.content, fragment, "my_fragment_tag").commit(); } } 

В Fragment :

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setRetainInstance(true);//toggle this } 

а также

 @Override public void onSaveInstanceState(Bundle outState) { outState.putString("test", "value"); super.onSaveInstanceState(outState); } 

Тест 1: жизненный цикл фрагмента при addToBackStack() , а setRetainInstance(true) не вызывается

  • onAttach ()
  • OnCreate ()
  • onCreateView ()
  • onActivityCreated ()
  • OnStart ()
  • onResume ()

[Устройство повернуто от портрета к пейзажу]

  • OnPause ()
  • onSaveInstanceState ()
  • OnStop ()
  • onDestroyView ()
  • OnDestroy ()
  • onDetach ()
  • onAttach ()
  • OnCreate ()
  • OnCreateView () с пакетом param! = Null
  • OnStart ()
  • onResume ()

Тест 2 и 3: вызовы жизненного цикла фрагмента с setRetainInstance(true) , addToBackStack() вызываемый / не вызываемый (тот же результат):

  • onAttach ()
  • onCreateView ()
  • onActivityCreated ()
  • OnStart ()
  • onResume ()

[Устройство повернуто от портрета к пейзажу]

  • OnPause ()
  • onSaveInstanceState ()
  • OnStop ()
  • onDestroyView ()
  • onDetach ()
  • onAttach ()
  • OnCreateView () с пакетом param == null
  • OnStart ()
  • onResume ()