39

Ho sviluppato un'applicazione in Honeycomb e sto usando i frammenti.
Questa è la mia appMantieni l'oggetto Frammento durante la rotazione

  • ho un'attività (Say A1) e dal fatto che è un frammento
  • Inizialmente questo frammento tenere l'oggetto frammento oggetto dire (F1)
  • Poi a seconda della azioni utente può cambiare ad altri oggetti F2, F3 ....

ciò che il mio problema è

quando l'utente ruota il dispositivo l'attività viene ricreata e che rendono F1 come l'oggetto frammento, anche se prima di ruotare non era
What is the way to retain the fragment object while rotating?
ho usato setRetainInstance(true); ma non ha funzionato per me
E devo aggiunto il frammento di codice nella mia funzione onCreate come questo

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

risposta

53

per impostazione predefinita Android manterrà gli oggetti frammento. Nel codice si imposta homeFragment nella funzione onCreate. Questo è il motivo per cui è sempre lo homeFragment o fl che mai impostato in onCreate.

Perché ogni volta che si ruota, onCreate eseguirà e impostare l'oggetto frammento al primo

Quindi la soluzione facile per voi è verificare se savedInstanceState fascio è nullo o meno e impostare l'oggetto frammento

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

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

cosa devo fare in caso uso un attività con ViewPager che gestisce i frammenti? –

+0

@androiddeveloper prega. No seriamente quello che ho fatto è stato: super.onCreate (null); – Warpzit

+19

"Per impostazione predefinita, Android manterrà gli oggetti frammento" ... non è vero. Android creerà nuovi oggetti sulle modifiche di orientamento, a meno che non venga chiamato 'setRetainInstance (true)'. Non confondere questo con Android ricollegando automaticamente i frammenti. Non sono la stessa cosa. Controlla le tracce riportate da S.D. su [questa risposta] (http://stackoverflow.com/a/12641575/2619107). – Rafa

34

È necessario assegnare al frammento un tag univoco e controllare se questo frammento è già stato aggiunto o meno all'attività.

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

verificare se savedInstanceState è nullo non è un modo sicuro per verificare se il frammento è già impostata - funziona in molti casi, ma in alcuni casi (ad esempio quando il dispositivo è acceso memoria bassa), Android potrebbe uccidere la tua attività, che potrebbe interrompere la tua applicazione.

Per vedere questo in azione, selezionare "Non mantenere attività" nelle opzioni di sviluppo del dispositivo (l'impostazione è disponibile in Android 4.0+, non sono sicuro delle versioni precedenti). Quando apri una nuova attività, la tua prima attività viene distrutta. Quando si ritorna ad esso (premendo indietro), viene creato di nuovo, e salvatoInstanceState è non null. Tuttavia, il tuo frammento non è più nell'attività e devi aggiungerlo di nuovo.

EDIT - che mostra il principio originale, ma con 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; 
     } 
    } 
} 

questo viene in particolarmente utile se si desidera modificare il frammento (in questo caso mHomeFragment) dopo aver ruotato il dispositivo

+0

Anche se ho già utilizzato la risposta fornita da @labeeb, ritengo che il controllo dell'unicità del 'tag' sia l'approccio migliore. –

+0

interessante! Sembra quindi che Google debba aggiornare il codice del modello. –

0

ho definito un Fragment nel layout dell'attività, onSaveInstanceState nel Fragment viene chiamato, ma il savedInstanceStateBundle in Frammento onCreatView viene come null.

Il motivo era che la mia Fragment non hanno un ID in XML:

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

Uso onAttachFragment() nel vostro Activity per riassegnare l'oggetto:

@Override 
public void onAttachFragment(Fragment fragment) { 
    if (fragment instanceof MyFragment) 
     this.myFragment = (MyFragment) fragment; 
} 
Problemi correlati