为什么我要避免片段中的非默认构造函数?

我正在用 Fragments创建一个应用程序,在其中一个应用程序中,我创建了一个非默认构造函数,并得到了以下警告:

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

有人能告诉我为什么这不是个好主意吗?

你还能建议我怎么做吗:

public static class MenuFragment extends ListFragment {
public ListView listView1;
Categories category;


//this is my "non-default" constructor
public MenuFragment(Categories category){
this.category = category;
}....

不使用非默认构造函数?

93352 次浏览

创建一个 bundle 对象并插入数据(在本例中是 Category对象)。请注意,除非该对象是可序列化的,否则不能将其直接传递到 bundle 中。 我认为最好是在片段中构建对象,并且只在 bundle 中放入一个 id 或其他内容。这是创建和附加一个 bundle 的代码:

Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);

然后,在片段访问数据中:

Type value = getArguments().getType("key");

仅此而已。

您的 Fragment不应该有构造函数,因为 FragmentManager是如何实例化它的。 您应该有一个定义了所需参数的 newInstance()静态方法,然后绑定它们并将它们设置为片段的参数,稍后您可以使用 Bundle参数访问这些参数。

例如:

public static MyFragment newInstance(int title, String message) {
MyFragment fragment = new MyFragment();
Bundle bundle = new Bundle(2);
bundle.putInt(EXTRA_TITLE, title);
bundle.putString(EXTRA_MESSAGE, message);
fragment.setArguments(bundle);
return fragment ;
}

onCreate上阅读这些论点:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
title = getArguments().getInt(EXTRA_TITLE);
message = getArguments().getString(EXTRA_MESSAGE);


//...
}

这样,如果分离并重新附加,对象状态可以通过参数存储,就像附加到 Intentbundles一样。

似乎没有一个答案回答“为什么使用 bundle 传递参数而不是非默认构造函数”

之所以应该通过 bundle 传递参数,是因为当系统恢复 fragment(例如在配置更改时)时,它会自动恢复 bundle

onCreate或者 onCreateView这样的回调函数应该从 bundle中读取参数——这样你就可以保证将 fragment的状态正确地恢复到 fragment初始化时的状态(注意这个状态可能不同于传递给 onCreate/onCreateViewonSaveInstanceState bundle)

使用静态 newInstance()方法的建议只是一个建议。你可以使用一个非缺省构造函数,但是要确保在构造函数体内的 bundle中填充了初始化参数。并在 onCreate()onCreateView()方法中读取这些参数。

如果您使用某个类的参数

SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
MyFragment f = new MyFragment();
f.mSomeInstance = someInstance;
return f;
}

我认为,静态构造函数和两个构造函数(空的和参数化的一个,将参数存储到片段的参数包中)之间没有区别,最有可能的是,这个经验法则是为了降低忘记在 Java 中实现 no-arg 构造函数的概率而创建的,当重载出现时,这个概率不会隐式生成。

在我的项目中,我使用 Kotlin,并使用主要的 no-arg 构造函数和次要的参数构造函数来实现片段,这些构造函数只是将它们存储到一个 bundle 中,并将其设置为片段参数,一切都很正常。

如果片段在配置更改后使用非默认构造函数,则片段将丢失所有数据。