Vor kurzem war ich es leid, ständig String
-Schlüssel kennen zu müssen, um beim Erstellen meiner Bundles
Argumente an Fragments
zu übergeben. Also entschied ich mich, Konstruktoren für meine Fragments
zu erstellen, die die Parameter, die ich einstellen wollte, übernehmen und diese Variablen mit den korrekten Bundles
-Schlüsseln in die String
setzen, so dass andere Fragments
und Activities
nicht mehr benötigt werden, um diese Schlüssel zu kennen.
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);
}
Und dann ziehe ich diese Argumente wie gewohnt heraus.
@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];
}
}
Lint hatte jedoch ein Problem damit und sagte, keine Unterklassen von Fragment
mit Konstruktoren mit anderen Parametern zu haben, weshalb ich @SuppressLint("ValidFragment")
verwenden musste, um die App sogar auszuführen. Die Sache ist, dieser Code funktioniert einwandfrei. Ich kann ImageRotatorFragment(int imageResourceId)
oder die alte Schulmethode ImageRotatorFragment()
verwenden und setArguments()
manuell aufrufen. Wenn Android das Fragment neu erstellen muss (Orientierungsänderung oder zu wenig Arbeitsspeicher), ruft es den ImageRotatorFragment()
-Konstruktor auf und übergibt dann das gleiche Argument Bundle
mit meinen Werten, die korrekt festgelegt werden.
Ich habe also nach dem "vorgeschlagenen" Ansatz gesucht und sehe viele Beispiele, die newInstance()
verwenden, um Fragments
mit Parametern zu erstellen. Dies scheint das gleiche zu tun, was mein Konstruktor tut. Also habe ich mir ein eigenes gemacht, um es zu testen, und es funktioniert genauso einwandfrei wie zuvor, ohne dass Lint darüber jammert.
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;
}
Ich persönlich finde, dass die Verwendung von Konstruktoren eine weitaus üblichere Praxis ist, als zu wissen, newInstance()
zu verwenden und Parameter zu übergeben. Ich glaube, Sie können dieselbe Konstruktortechnik mit Aktivitäten verwenden, und Lint wird sich nicht darüber beklagen. Meine Frage ist im Grunde, warum will Google nicht, dass Sie Konstruktoren mit Parametern für Fragments
verwenden?
Meine einzige Vermutung ist, dass Sie nicht versuchen, eine Instanzvariable ohne die Bundle
zu setzen, die nicht gesetzt wird, wenn die Fragment
neu erstellt wird. Durch die Verwendung einer static newInstance()
-Methode kann der Compiler nicht auf eine Instanzvariable zugreifen.
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
mImageResourceId = imageResourceId;
}
Ich glaube immer noch nicht, dass dies Grund genug ist, die Verwendung von Parametern in Konstruktoren zu verbieten. Hat noch jemand Einblick in das?
Ich persönlich finde, dass die Verwendung von Konstruktoren eine weit verbreitete Praxis ist, als zu wissen, wie man newInstance () verwendet und Parameter übergibt.
Die Methode factory pattern wird in der modernen Softwareentwicklung relativ häufig verwendet.
Im Grunde ist meine Frage: Warum will Google nicht, dass Sie Konstruktoren mit Parametern für Fragmente verwenden?
Sie haben Ihre eigene Frage beantwortet:
Meine einzige Vermutung ist, dass Sie nicht versuchen, eine Instanzvariable ohne das Bundle festzulegen. Dies wird nicht festgelegt, wenn das Fragment neu erstellt wird.
Richtig.
Ich glaube immer noch nicht, dass dies Grund genug ist, die Verwendung von Parametern in Konstruktoren zu verbieten.
Sie sind zu Ihrer Meinung herzlich willkommen. Sie können diese Lint-Prüfung gerne deaktivieren, entweder auf Konstruktorebene oder pro Arbeitsbereich.
Android stellt nur Fragmente wieder her, die mit dem Standardkonstruktor abgetötet werden. Daher gehen alle Initialisierungen in zusätzlichen Konstruktoren verloren.