Je me suis récemment fatigué de devoir constamment connaître les clés String
pour passer des arguments en Bundles
lors de la création de ma Fragments
. J'ai donc décidé de créer des constructeurs pour ma Fragments
qui prendraient les paramètres que je voulais définir et de placer ces variables dans la Bundles
avec les clés String
correctes, éliminant ainsi le besoin d'autres Fragments
et Activities
ayant besoin de connaître ces clés.
public ImageRotatorFragment() {
super();
Log.v(TAG, "ImageRotatorFragment()");
}
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
// Get arguments passed in, if any
Bundle args = getArguments();
if (args == null) {
args = new Bundle();
}
// Add parameters to the argument bundle
args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
setArguments(args);
}
Et puis je tire ces arguments comme d'habitude.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
// Set incoming parameters
Bundle args = getArguments();
if (args != null) {
mImageResourceId = args.getInt(KEY_ARG_IMAGE_RES_ID, StaticData.getImageIds()[0]);
}
else {
// Default image resource to the first image
mImageResourceId = StaticData.getImageIds()[0];
}
}
Cependant, Lint a contesté cette affirmation en disant de ne pas avoir de sous-classes de Fragment
avec des constructeurs avec d'autres paramètres, ce qui m'oblige à utiliser @SuppressLint("ValidFragment")
pour même exécuter l'application. Le fait est que ce code fonctionne parfaitement. Je peux utiliser ImageRotatorFragment(int imageResourceId)
ou la méthode old school ImageRotatorFragment()
et appeler setArguments()
manuellement dessus. Lorsque Android a besoin de recréer le fragment (changement d'orientation ou faible mémoire), il appelle le constructeur ImageRotatorFragment()
, puis transmet le même argument Bundle
avec mes valeurs, qui sont définies correctement.
J'ai donc recherché l'approche "suggérée" et ai vu beaucoup d'exemples utilisant newInstance()
pour créer Fragments
avec des paramètres, ce qui semble faire la même chose que mon constructeur. J'ai donc fait le mien pour le tester, et cela fonctionne aussi parfaitement qu'avant, moins Lint qui se lamente à ce sujet.
public static ImageRotatorFragment newInstance(int imageResourceId) {
Log.v(TAG, "newInstance(int imageResourceId)");
ImageRotatorFragment imageRotatorFragment = new ImageRotatorFragment();
// Get arguments passed in, if any
Bundle args = imageRotatorFragment.getArguments();
if (args == null) {
args = new Bundle();
}
// Add parameters to the argument bundle
args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
imageRotatorFragment.setArguments(args);
return imageRotatorFragment;
}
Personnellement, je trouve que l’utilisation de constructeurs est une pratique beaucoup plus courante que de savoir utiliser newInstance()
et de passer des paramètres. Je crois que vous pouvez utiliser cette même technique de constructeur avec Activités et Lint ne s'en plaindra pas. En gros, ma question est la suivante: pourquoi Google ne veut-il pas que vous utilisiez des constructeurs avec des paramètres pour Fragments
?
Ma seule hypothèse est de ne pas essayer de définir une variable d'instance sans utiliser la variable Bundle
, qui ne sera pas définie lorsque la variable Fragment
sera recréée. En utilisant une méthode static newInstance()
, le compilateur ne vous laissera pas accéder à une variable d'instance.
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
mImageResourceId = imageResourceId;
}
Je ne pense toujours pas que cela soit une raison suffisante pour interdire l'utilisation de paramètres dans les constructeurs. Quelqu'un d'autre a un aperçu de cela?
Je trouve personnellement que l'utilisation de constructeurs est une pratique beaucoup plus courante que de savoir utiliser newInstance () et de passer des paramètres.
Le modèle de méthode factory est utilisé assez fréquemment dans le développement de logiciels modernes.
En gros, ma question est la suivante: pourquoi Google ne veut-il pas que vous utilisiez des constructeurs avec des paramètres pour les fragments?
Vous avez répondu à votre propre question:
Ma seule hypothèse est de ne pas essayer de définir une variable d'instance sans utiliser Bundle, qui ne le sera pas lorsque le fragment sera recréé.
Correct.
Je ne pense toujours pas que cela soit une raison suffisante pour interdire l'utilisation de paramètres dans les constructeurs.
Vous êtes les bienvenus à votre avis. Vous pouvez désactiver cette vérification, soit par constructeur, soit par espace de travail.
Android ne recrée que les fragments qu'il tue à l'aide du constructeur par défaut. Ainsi, toute initialisation que nous effectuons dans des constructeurs supplémentaires sera perdue. Par conséquent, les données seront perdues.