2012-11-16 9 views
23

docs na setRetainInstance powiedzieć:jak mogę dzielić rzeczy z Fragmentami z setRetainInstance (true) i dodawać je do backstack?

ten może być używany tylko z fragmentów nie na tylnym stosie.

więc zacząłem grać z tym.

Mam jedno Aktywny dodaje pierwszego fraga

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

następnie z tego frag uruchomić metodę z dominującą aktywność, która dodaje frag B backstack

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

następnie tworzę dziennika wiad z onCreate, onDestroy, onSaveInstanceState, onActivityCreated ... itd.

Próbuję dwóch wersji tego procesu. Obracanie urządzenia na każdym fragmencie.

  1. domyślny

Wszystko jest zgodnie z oczekiwaniami. onCreate, onDestroy na fragmentach ognia

  1. setRetainInstance (true)

Wszystko zgodnie z oczekiwaniami ?. onCreate, onDestroy na fragmentach nie ognia

i wszystko wydaje się działać, gdy fragmenty są w backstack .. więc dlaczego doktorzy mówią, że nie powinienem go używać? Jakie są scenariusze, w których mogę mieć kłopoty?

dzięki

+0

Po naciśnięciu przycisku wstecz kiedy zaczniesz widzieć różnicę. Tak na przykład jeśli setRetainInstance został użyty na fragment widoku szczegółów, który tymczasowo się pojawia, naciśnięcie klawisza back może spowodować wyjście z aplikacji zamiast zamykania tego fragmentu widoku szczegółów tymczasowych. –

+0

Dzięki Marco, czy udało ci się odtworzyć ten problem? proszę podziel się, jeśli tak. Mogę cofnąć się bez problemu. Przetestowałem kilka scenariuszy i zawsze fragment szczegółów jest właściwie niszczony, gdy naciskam, podczas gdy oba fragi mają setRetainInstance (true). – AndroidGecko

+0

Odzyskuję mój komentarz. Widzę podobne zachowanie ... –

Odpowiedz

24

Updated odpowiedź:

Jakie są scenariusze, w których mogę się w kłopoty?

Dodając Fragment do stosu z powrotem i przechodzącej Bundle w Fragment od onSaveInstanceState() do onCreateView() na zmianę konfiguracji. Wywołanie setRetainInstance(true) ustawi Bundle na wartość null przy zmianie konfiguracji.

(Nie jestem pewien, czy programista rzeczywiście spróbowałby tego, ponieważ użycie setRetainInstance(true) powoduje, że jest zbędny, ale nie widziałem zachowania udokumentowanego w dokumentach API, więc napisałem tę odpowiedź).

Jeśli oba addToBackStack() i setRetainInstance(true) są nazywane, setRetainInstance() częściowo zmienia Fragment cyklu życia wywołań metod i wartości parametrów na zmiany konfiguracji, w porównaniu do wywoływania tylko addToBackStack().

szczególności w poniższym teście, patrząc różnice między wywołaniem tylko addToBackStack() i nazywając setRetainInstance(true) jak również, a widząc, co dzieje się na zmianę konfiguracji:

Wywołanie addToBackStack() ale nie setRetainInstance(true);

  • onCreate() i onDestroy() są nazywane.
  • pakiet przekazany od onSaveInstanceState() jest odbierany jako parametr w onCreateView().

Zadzwoń zarówno addToBackStack() i setRetainInstance(true):

  • onCreate() i onDestroy() nie są nazywane. Jest to opisane w dokumentach API.
  • pakiet nie został odebrany w numerze w numerze onCreateView(). Przekazany Bundle ma wartość NULL.

Test z zapisanymi wywołań metod i parametrów testowanych zerową:

W Activity:

@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(); 
    } 
} 

W Fragment:

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

i

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

Test 1: Fragment cyklu kiedy addToBackStack() nazywa i setRetainInstance(true) jest nie zwanego

  • onAttach()
  • onCreate()
  • onCreateView()
  • onActivityCreated()
  • onStart()
  • onResume()

[Urządzenie obraca się z położenia pionowego do poziomego]

  • OnPause()
  • onSaveInstanceState()
  • OnStop()
  • onDestroyView()
  • onDestroy()
  • onDetach()
  • onAttach()
  • onCreate()
  • onCreateView() z wiązki param!= NULL
  • onStart()
  • onResume()

Test 2 & 3: fragment cyklu połączenia z setRetainInstance(true) nazwie, addToBackStack() nazwie/nie jest wywoływana (ten sam rezultat)

  • onAttach()
  • onCreateView()
  • onActivityCreated()
  • onStart()
  • onResume()

[Urządzenie obraca się z położenia pionowego do góry]

  • OnPause()
  • onSaveInstanceState()
  • OnStop()
  • onDestroyView()
  • onDetach()
  • onAttach()
  • onCreateView() z wiązki param == null
  • onStart()
  • onResume()
+1

"podczas gdy dodawanie fragmentu do backstacku daje wyniki w tym cyklu życia" - czy masz do tego odnośnik? Patrząc na kod, nie widzę, gdzie wywołanie 'onAttach()' zależy od tego, czy fragment ma zostać dodany do tylnego stosu. Dzięki! – CommonsWare

+0

Dzięki za wskazanie tego. Miałem na myśli nawigację wstecz, a nie tylko po dodaniu fragmentu. Zmieniłem zdanie, aby wyraźniej wyrazić, o co mi chodzi. To jest referencja, której użyłem: http://assets.en.oreilly.com/1/event/68/Fragments%20for%20All%20Presentation.pdf. Sekcja 19: "Jeśli wywołasz metodę addToBackStack() podczas usuwania lub zastępowania fragmentu: (...) Jeśli użytkownik nawiguje z powrotem, system wywołuje onCreateView(), onActivityCreated(), onStart() i onResume() na fragmencie . " –

+0

Kolejne odniesienie to profesjonalne tworzenie aplikacji Android 4 przez Reto Meier, rysunek 4.9 (podsumowanie cyklu życia fragmentu) "Fragment.onCreateView() (...) Fragment powraca do układu z backstacku". –

Powiązane problemy