39

Mam opracowaną aplikację w Plaster miodu i używam fragmentów.
To moja aplikacjaZatrzymaj obiekt Fragment podczas obracania

  • Mam Aktywny (Say A1) oraz tym, że jest to fragment
  • Początkowo ten fragment trzymać przedmiot jeden obiekt fragment powiedzieć (F1)
  • Następnie w zależności od działania użytkowników może zmienić do innych obiektów F2, F3 ....

Jaki jest mój problem

gdy użytkownik obrócić urządzenie aktywność jest odtwarzany i które sprawiają, że F1 jako przedmiot fragmentu choć przed obróceniem nie było
What is the way to retain the fragment object while rotating?
użyłem setRetainInstance(true); ale to nie działa dla mnie
I mam dodany przez fragment kodu w moim onCreate funkcji jak ten

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 

    Fragment homeFragment = new Home(); 
    fragmentTransaction.add(R.id.mainFragement, homeFragment); 
    fragmentTransaction.commit(); 
} 

Odpowiedz

53

Domyślnie Android zachowa obiekty fragmentu. W swoim kodzie ustawiasz homeFragment w swojej funkcji onCreate. Dlatego zawsze jest jakiś homeFragment lub fl, jaki kiedykolwiek ustawiłeś w onCreate.

Bo kiedy tylko obracać, onCreate wykona i ustawić obiekt fragment pierwszego jednym

więc proste rozwiązanie dla Ciebie, to sprawdzić, czy savedInstanceState wiązka jest null lub nie i ustawić obiekt fragment

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(null == savedInstanceState) { 
     // set you initial fragment object 
    } 
} 
+1

co należy zrobić w przypadku używam aktywność z ViewPager, który obsługuje fragmenty? –

+0

@androiddeveloper pray. Nie poważnie, co zrobiłem to: super.onCreate (null); – Warpzit

+19

"Domyślnie android zachowuje obiekty fragmentów" ... nie jest prawdziwe. Android utworzy nowe obiekty na zmiany orientacji, chyba że wywoływana jest 'setRetainInstance (true)'. Nie myl tego z Androidem, automatycznie ponownie dołączając fragmenty. To nie to samo. Sprawdź ślady zgłoszone przez S.D. w [tej odpowiedzi] (http://stackoverflow.com/a/12641575/2619107). – Rafa

34

Musisz nadać Fragmentowi unikalny znacznik i sprawdź, czy ten Fragment jest już dodany do Twojej aktywności już, czy nie.

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    String tag = "my_fragment"; 
    FragmentManager fragmentManager = getFragmentManager(); 
    if(fragmentManager.findFragmentByTag(tag) == null) { 
     FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 
     Fragment homeFragment = new Home(); 
     fragmentTransaction.add(R.id.mainFragement, homeFragment, tag); 
     fragmentTransaction.commit(); 
    } 
} 

Sprawdzenie czy savedInstanceState jest null nie jest bezpiecznym sposobem na sprawdzenie, czy fragment jest już ustawiony - to będzie działać w większości przypadków, ale w niektórych przypadkach (na przykład, gdy urządzenie znajduje się na małej ilości pamięci), Android może zabić twoją aktywność, która może złamać twoją aplikację.

Aby zobaczyć to w akcji, zaznacz "Nie zatrzymuj aktywności" w opcjach programowania urządzenia (ustawienie jest dostępne w systemie Android 4.0+, nie wiesz o wcześniejszych wersjach). Gdy otworzysz nową aktywność, twoja pierwsza aktywność zostanie zniszczona. Gdy do niego wrócisz (przez naciśnięcie), zostanie ono utworzone ponownie, a zapisana wartośćInstanceState ma wartość , a nie null. Jednak Twój fragment nie znajduje się już w działaniu i musisz go dodać ponownie.

EDIT - Pokazuje oryginalną zasadę ale z SupportFragmentManager

public class ActivityAwesome extends AppCompatActivity 
{ 
    private final String TAG = getClass().getSimpleName(); 
    private FragmentHome mHomeFragment; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     Fragment fragment = fragmentManager.findFragmentByTag(TAG); 
     if(fragment == null) 
     { 
      // Create the detail fragment and add it to the activity using a fragment transaction. 
      mHomeFragment = new FragmentHome(); 
      fragmentManager.beginTransaction() 
        .add(R.id.fragment_container, mHomeFragment, TAG) 
        .commit(); 
     } 
     else 
     { 
      // get our old fragment back ! 
      mHomeFragment = (FragmentHome)fragment; 
     } 
    } 
} 

ten jest w szczególności przydatna, jeśli chcesz manipulować fragment (w tym przypadku mHomeFragment) po obróceniu urządzenia

+0

Chociaż użyłem odpowiedzi dostarczonej przez @labeeb wcześniej, myślę, że sprawdzenie unikalnego 'tag' jest najlepszym podejściem. –

+0

interesujące! Wygląda na to, że Google musi zaktualizować swój kod szablonu. –

0

zdefiniowałem Fragment w układzie działania, onSaveInstanceState w Fragment zostaje wywołany, ale savedInstanceStateBundle w pliku onCreatView Fragmentu ma wartość NULL.

Powodem było to, że mój Fragment nie mieć identyfikator w XML:

android:id="@+id/compass_fragment" ... 
3

Zastosowanie onAttachFragment() w Activity o przeniesieniu obiektu:

@Override 
public void onAttachFragment(Fragment fragment) { 
    if (fragment instanceof MyFragment) 
     this.myFragment = (MyFragment) fragment; 
} 
Powiązane problemy