2012-08-27 15 views
6

Moja aplikacja na Androida ma ActionBar, która zmienia, który Fragment zajmuje określony numer FrameLayout. Próbuję użyć onSaveInstanceState, aby zapisać stan fragmentu po zmianie karty, aby można go było odzyskać w onCreateView.Odłączanie fragmentu bez wyzwalania onSaveInstanceState()

Problem polega na tym, że onSaveInstanceState nigdy nie jest wywoływany. Wywoływane są metody Fragment, ale Bundle dostarczone do onCreateView pozostaje puste.

Czy ktoś może mi wytłumaczyć, kiedy rzeczywiście nazywa się onSaveInstanceState, w jaki sposób mogę upewnić się, że zostanie wywołany podczas przełączania kart lub najlepszą praktyką do zapisywania i przywracania stanu Fragment po odłączeniu i ponownym podłączeniu?

Fragment:

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.event_log, container, false); 

    // Retrieve saved state 
    if (savedInstanceState != null){ 
     System.out.println("log retrieved"); 
    } else { 
     System.out.println("log null"); 
    } 

    return view; 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    System.out.println("log saved"); 
    super.onSaveInstanceState(outState); 
    // more code 
} 

aktywny:

/** 
* Detach the current Fragment, because another one is being attached. 
*/ 
@Override 
public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
    if (tab.getText().equals(getString(R.string.tab_events))){ 
     if (frEventLog != null) { 
      ft.detach(frEventLog); 
    } 
} 
+0

Możliwa kopię http://stackoverflow.com/questions/8503629/fragments-onsaveinstancestate-never-called – DeeV

+0

co jest frEventLog? –

Odpowiedz

8

Fragment#onSaveInstanceState nazywa się tylko wtedy, gdy Activity gospodarzem Fragment jest zniszczona i jest szansa, że ​​można wrócić do tej samej działalności i fragment nadal jest dodawany do FragmentManager. Najczęstszym przypadkiem byłaby rotacja ekranu.

Myślę, że Twój Fragment będzie musiał na przykład wykonać setRetainInstance(true) w onCreate. Nie jestem do końca pewien co do tego punktu.

Powinieneś również zobaczyć tę metodę, która jest wywoływana po naciśnięciu przycisku home na przykład. To zniszczy działanie, ale możesz wrócić do niego, korzystając np. Z listy zadań.

Jeśli po prostu detach() fragment, wszystko co musisz zrobić, aby go odzyskać, to poprosić o numer FragmentManager.

Istnieją dwa przykłady powinieneś rzucić okiem na:

ActionBar FragmentTabs i TabHost FragmentTabs

Przykład TabHost wykorzystuje

ft.add(containerId, fragment, tag); 
// later 
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag); 

znaleźć wystąpień wcześniej dodany Fragment s, działa aż do ciebie remove() a Fragment


Jeśli chodzi o onCreateView/onDestroyView: Jest to wywoływane, gdy fragment zostanie odłączony, ponieważ przy następnym dołączeniu go trzeba utworzyć nowy View. Zauważ, że Fragment#onDetached() nie jest wywoływany, gdy ten fragment jest nadal dołączony do . Jest oderwany od hierarchii widoku.


Jest jeszcze inny dobry przykład o tym, jak zachować stan fragment/jak wykorzystać fragmenty zachować stan w Android Training - Caching Bitmaps.

To przykład brakuje krytyczną linię choć:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { 
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG); 
    if (fragment == null) { 
     fragment = new RetainFragment(); 
     fm.beginTransaction().add(fragment, TAG).commit(); // << add this 
    } 
    return fragment; 
} 
+0

Dziękuję za odpowiedź. Miałem wrażenie, że używanie setRetainInstance (true) będzie wymagać dużej pamięci, ponieważ oznaczałoby to przechowywanie zakładek, a nie ich niszczenie i ponowne tworzenie, ale spróbuję. Czy muszę zdobyć moje Fragmenty za pośrednictwem FragmentManager lub czy mogę zachować odniesienie do nich w polu? – Dan

+0

Nie potrzebujesz w ogóle odniesienia. FragmentManager ma odnośniki do nich, ale możesz je dodać, jeśli nie dodasz przecieków pamięci. Intensywność pamięci zależy od tego, ile użyjesz w swoich fragmentach, która może być bliska 0, jeśli robisz to dobrze – zapl

+0

Myślę, że mam to posortowane teraz za pomocą twojego pierwszego przykładu. Mój problem polegał na tym, że miałem jakiś kod w metodzie onActivityCreated() Fragmenta, który w zasadzie go zresetował, ponieważ nie zdawałem sobie sprawy, że ta metoda będzie uruchamiana więcej niż raz. – Dan

Powiązane problemy