Alors que @yydl donne une raison convaincante pour laquelle la newInstance
méthode est meilleure:
Si Android décide de recréer votre fragment plus tard, il appellera le constructeur sans argument de votre fragment. Surcharger le constructeur n'est donc pas une solution.
il est tout à fait possible d'utiliser un constructeur . Pour voir pourquoi cela est, nous devons d'abord voir pourquoi la solution de contournement ci-dessus est utilisée par Android.
Avant qu'un fragment puisse être utilisé, une instance est nécessaire. Android appelle YourFragment()
(le constructeur sans arguments ) pour construire une instance du fragment. Ici, tout constructeur surchargé que vous écrivez sera ignoré, car Android ne peut pas savoir lequel utiliser.
Pendant la durée de vie d'une activité, le fragment est créé comme ci-dessus et détruit plusieurs fois par Android. Cela signifie que si vous placez des données dans l'objet fragment lui-même, elles seront perdues une fois le fragment détruit.
Pour contourner ce problème, Android vous demande de stocker les données à l'aide d'un Bundle
(appel setArguments()
), auquel vous pourrez ensuite accéder YourFragment
. Les arguments bundle
sont protégés par Android et sont donc garantis persistants .
Une façon de définir cet ensemble consiste à utiliser une newInstance
méthode statique :
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;
}
Cependant, un constructeur:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
peut faire exactement la même chose que la newInstance
méthode.
Naturellement, cela échouerait et c'est l'une des raisons pour lesquelles Android souhaite que vous utilisiez la newInstance
méthode:
public YourFragment(int data) {
this.data = data; // Don't do this
}
Pour plus d'explications, voici la classe de fragments d'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;
}
Notez qu'Android demande que les arguments ne soient définis qu'à la construction et garantit qu'ils seront conservés.
EDIT : Comme indiqué dans les commentaires de @JHH, si vous fournissez un constructeur personnalisé qui nécessite des arguments, alors Java ne fournira pas votre fragment avec un constructeur par défaut sans argument . Donc, cela vous obligerait à définir un constructeur sans argument , qui est du code que vous pourriez éviter avec la newInstance
méthode d'usine.
EDIT : Android ne permet plus d'utiliser un constructeur surchargé pour les fragments. Vous devez utiliser la newInstance
méthode.