2013-02-19 14 views
6

Sto provando a decidere e mostrare un frammento nel metodo di attività sul Risorsa, ma nel caso in cui venga scelto nuovamente un frammento aggiunto in precedenza, l'attività diventa vuota.Sostituire un frammento con se stesso non mostra nulla

codice di esempio (con un frammento):

@Override 
protected void onResume(){ 
    FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); 

    trans.replace(R.id.myLayout, fragA); 

    trans.commit(); 
    getSupportFragmentManager().executePendingTransactions(); 
} 

Con il codice di cui sopra, quando viene creato l'attività per la prima volta, mostra Fraga correttamente, ma nel caso in cui premere chiave domestica e quindi tornare alla mia attività (al fine di provocare di nuovo onResume), tutto diventa vuoto (sembra come fragA viene rimosso).

Sostituire un frammento aggiunto in precedenza si rimuove da solo? o come non perdere un frammento se viene sostituito da solo?

risposta

4

Non è possibile sostituire un frammento con se stesso. La prima metà di una sostituzione è una rimozione del frammento precedente a quell'id. Una volta rimosso un frammento, non può più essere aggiunto o utilizzato dal gestore dei frammenti (quindi la parte aggiuntiva della sostituzione non funzionerà correttamente).

A seconda del caso d'uso, si hanno due opzioni:

  1. creare un nuovo frammento, invece di riutilizzare l'istanza esistente
  2. utilizzare un altro metodo per vedere se il suo necessario per sostituire il vostro frammento

Infine, probabilmente non è necessario chiamare executePendingTransactions.

+0

Inizializzo ** fragA ** in * onCreate *, il che significa che continuo a fare riferimento al mio frammento. Quindi, perché non consente di aggiungerlo dopo aver rimosso quel frammento? – waqaslam

+0

A causa di esattamente quello che ho detto. Una volta rimossa un'istanza di un frammento, NON puoi aggiungerla più. È distrutto, finito, non più utilizzabile. –

+0

Un'altra cosa da verificare è che R.id.myLayout è l'ID del contenitore in cui desideri inserire il tuo frammento. Se lo è, prova a cambiare la chiamata sostitutiva per sostituirla (R.id.myLayout, new FragmentAClass()) –

4

Si può provare:

if(!(getSupportFragmentManager().findFragmentById(R.id.myLayout) instanceof FragmentA)) { 
    FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); 

    trans.replace(R.id.myLayout, fragA); 

    trans.commit(); 
} 

e presumo che Fraga è Fragmenta oggetto classe.

+0

'R.id.myLayout' punta al layout in cui viene iniettato ** fragA **. Non penso 'findFragmentById (R.id.myLayout)' mi farà riferimento al mio frammento. – waqaslam

+0

Se il proprio frammento si trova in questo contenitore, restituirà un riferimento a questo frammento iniettato. Quindi puoi verificare se è un'istanza della classe del tuo frammento. –

+0

funziona, ed è una soluzione piuttosto interessante se stai creando frammenti all'interno di frammenti. –

3

Infine, ho dovuto effettuare un controllo prima di sostituire i frammenti. Nel caso in cui sia richiesto un frammento (già aggiunto) per la sostituzione, ho dovuto verificare se è già stato aggiunto, quindi ignorare la sostituzione, altrimenti procedere. Ad esempio:

@Override 
protected void onResume() { 
    if (!fragA.isAdded()) { 
     FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); 
     trans.replace(R.id.myLayout, fragA); 
     trans.commit(); 
     //getSupportFragmentManager().executePendingTransactions(); //unnecessary 
    } 
} 
Problemi correlati