Mentre @yydl fornisce un motivo convincente sul perché il newInstance
metodo è migliore:
Se Android decide di ricreare il tuo frammento in un secondo momento, chiamerà il costruttore senza argomenti del tuo frammento. Quindi sovraccaricare il costruttore non è una soluzione.
è ancora del tutto possibile usare un costruttore . Per capire perché, innanzitutto dobbiamo vedere perché la soluzione sopra descritta viene utilizzata da Android.
Prima di poter utilizzare un frammento, è necessaria un'istanza. Chiamate Android YourFragment()
( nessun argomento costruttore ) per costruire un'istanza del frammento. Qui qualsiasi costruttore sovraccarico che scrivi verrà ignorato, poiché Android non può sapere quale utilizzare.
Nel corso della vita di un'attività il frammento viene creato come sopra e distrutto più volte da Android. Ciò significa che se si inseriscono dati nell'oggetto frammento stesso, questi verranno persi una volta che il frammento viene distrutto.
Per ovviare al problema, Android chiede di archiviare i dati utilizzando un Bundle
(chiamante setArguments()
), a cui è possibile accedere da YourFragment
. Gli argomenti bundle
sono protetti da Android e quindi sono garantiti come persistenti .
Un modo per impostare questo pacchetto è utilizzando un newInstance
metodo statico :
public static YourFragment newInstance (int data) {
YourFragment yf = new YourFragment()
/* See this code gets executed immediately on your object construction */
Bundle args = new Bundle();
args.putInt("data", data);
yf.setArguments(args);
return yf;
}
Tuttavia, un costruttore:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
può fare esattamente la stessa cosa del newInstance
metodo.
Naturalmente, ciò fallirebbe ed è uno dei motivi per cui Android vuole che tu usi il newInstance
metodo:
public YourFragment(int data) {
this.data = data; // Don't do this
}
Come ulteriore spiegazione, ecco la classe dei frammenti di Android:
/**
* Supply the construction arguments for this fragment. This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment. The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
}
Si noti che Android chiede che gli argomenti siano impostati solo durante la costruzione e garantisce che questi verranno conservati.
EDIT : Come sottolineato nei commenti di @JHH, se stai fornendo un costruttore personalizzato che richiede alcuni argomenti, Java non fornirà al tuo frammento un costruttore predefinito senza arg . Quindi questo richiederebbe di definire un costruttore no arg , che è il codice che potresti evitare con il newInstance
metodo factory.
EDIT : Android non consente più l'utilizzo di un costruttore sovraccaricato per i frammenti. È necessario utilizzare il newInstance
metodo