2013-04-08 20 views
5

Biorąc pod uwagę pokaz przepływu aplikacji w formie graficznej i tekstowej opisanej poniżej.Fragment, który nie znajduje się najwyżej w backstacku, zostaje wznowiony.

Application flow

  1. Fragment 1 jest najniższy fragment, ale nie w backstack ustawiając disallowAddToBackStack.
  2. Fragment 2 jest pchany na stos, używając fragmentTransaction.addToBackStack().
  3. Nowa instancja fragmentu 1 jest przesuwana na stos.
  4. Górny najbardziej fragment (fragment 1) jest wyskakiwany ze stosu.
  5. Aktywność 2 staje się pierwszym planie.
  6. Aktywność 1 staje się pierwszym planie.

Oto uogólniona metoda użyć do obsługi fragmenty:

private void changeContainerViewTo(int containerViewId, Fragment fragment, 
            Activity activity, String backStackTag) { 

    if (fragmentIsAlreadyPresent(containerViewId, fragment, activity)) { return; } 
    final FragmentTransaction fragmentTransaction = 
       activity.getFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(containerViewId, fragment); 
    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    if (backStackTag == null) { 
     fragmentTransaction.disallowAddToBackStack(); 
    } else { 
     fragmentTransaction.addToBackStack(backStackTag); 
    } 
    fragmentTransaction.commit(); 
} 

problem

gdy aktywność 1 CV w ostatnim etapie najniższy przykład fragmentu 1 zostaje również. W tym momencie fragment 1 zwraca null na getActivity().

Pytanie

  • Dlaczego jest fragmentem, który nie znajduje się na najwyższym na stosie wznowione?
  • Jeśli wznowienie fragmentu jest poprawne - jak mam obsłużyć oderwany fragment?
+0

Czy pierwsze fragmenty 1 i fragment 2 są używane w tym samym widoku kontenera i jakiej transakcji używasz w drugim etapie? – Evos

+0

Tak, Fragment1 i Fragment2 używają tego samego widoku kontenera. – JJD

+0

A co z typem transakcji: "zamień", "dodaj"? – Evos

Odpowiedz

1

nie widzę w jaki sposób to się stało, chyba że (w zależności od sposobu opisane etapy) masz źle jak fragmentTransaction.addToBackStack() działa: zarządza, które transakcje są umieszczane w backstack, nie fragmenty.

Od android docs:

Dzwoniąc addToBackStack(), transakcja zastąpić zostanie zapisany w powrotem stosu, dzięki czemu użytkownik może odwrócić transakcję i przywrócić poprzedni fragment naciskając przycisk Wstecz .

Więc jeśli krok 2 wyglądało coś takiego w postaci kodu:

fragmentTransaction.replace(containerViewId, fragment2); 
fragmentTransaction.addToBackStack(); 
fragmentTransaction.commit(); 

i swoją Krok 3:

fragmentTransaction.disallowAddToBackStack()//or just no call to addToBackStack - you do not say 
fragmentTransaction.replace(containerViewId, newfragment1); 
fragmentTransaction.commit(); 

W tym momencie Fragment2 zostanie usunięty z backstack i twój backstack składa się z dwóch instancji Fragment1. w kroku 4 wyskoczysz z góry, co oznacza, że ​​powinieneś mieć najniższy Fragment1 teraz na górze.

To wyjaśnia, dlaczego jest to wznowiony fragment, jeśli powrócisz do działania. Ale nie, obawiam się, dlaczego jest wyraźnie oderwany od swojej działalności.

+0

Zauważyłem, że nazywacie '.disallowAddToBackStack()' przed '.replace()'. Zobacz moje zaktualizowane pytanie. Czy to może być problem? – JJD

+1

Nie, kolejność nie ma znaczenia. to tylko atrybuty ustawione podczas budowania transakcji, nie używane, dopóki nie wywołasz w końcu commit. – salfon

+0

jeśli obecnie robi coś podobnego STEP1) 'changeContainerViewTo (containerId, afragment1, aktywność, null)' STEP2) 'changeContainerViewTo (containerId, afragment2, aktywność, tag)' step3) 'changeContainerViewTo (containerId, afragment1, aktywność , null) ' prawdopodobnie nie robi to, co chcesz - spróbuj podać wartość null dla parametru znacznika kroku2 i wartość inną niż null dla parametru znacznika kroku 3. krótko mówiąc, chcesz tylko wywołać addToBackStack, gdy fragment BEING zamieniony w transakcji jest tym, co chcesz zapisać w historii zwrotów. – salfon

2

Gdy nie pokazuje interfejsu użytkownika, a następnie przychodzi do wyświetlenia interfejsu użytkownika, powiązany obiekt FragmentManager umiera wraz ze wszystkimi fragmentami i trzeba przywrócić jego stan.

Jako documentation mówi:

Istnieje wiele sytuacji, w których fragment może być głównie rozdarty dół (jak w przypadku umieszczenia na tylnej stosu bez UI pokazano), ale jego stan nie będą zapisywane, dopóki jego własna aktywność faktycznie musi uratować jej stan.

W swojej ActivityonSaveInstanceState i onRestoreInstanceState, spróbuj oszczędzając Fragment odniesienia, a następnie przywrócić je z czymś takim:

public void onSaveInstanceState(Bundle outState){ 
    getFragmentManager().putFragment(outState,"myfragment", myfragment); 
} 
public void onRetoreInstanceState(Bundle inState){ 
    myFragment = getFragmentManager().getFragment(inState, "myfragment"); 
} 

Spróbuj tego i mieć szczęście! :-)

1

System operacyjny Android może i będzie tworzyć i niszczyć fragmenty, jeśli uzna to za stosowne. Najprawdopodobniej dzieje się to po uruchomieniu działania 2 i powrocie do działania 1. Weryfikowałbym na pewno, czy to nie jest aktywnie wyświetlany fragment. Prawdopodobnie dzieje się tak, że widzisz, że wykonałeś kilka kroków tworzenia fragmentu 1, zanim wykonasz kroki tworzenia dla fragmentu 2.

Jeśli chodzi o obsługę oddzielonych fragmentów, powinieneś spojrzeć na to page. Istotą tego jest, że powinieneś używać getActivity tylko w niektórych funkcjach fragmentów (w oparciu o fragment life cycle). Może to oznaczać, że musisz przenieść część swojej logiki do innych funkcji.

Powiązane problemy