尽管@yydl给出了为什么该newInstance
方法更好的令人信服的理由:
如果Android决定稍后再创建您的片段,它将调用片段的无参数构造函数。因此,重载构造函数不是解决方案。
仍然有可能使用构造函数。要了解其原因,首先我们需要了解Android为什么使用上述解决方法。
在使用片段之前,需要一个实例。Android调用YourFragment()
(无参数构造函数)构造片段的实例。在这里,您编写的所有重载构造函数都将被忽略,因为Android无法确定要使用哪个构造函数。
在Activity的生存期内,片段会按上述方式创建并被Android多次破坏。这意味着,如果将数据放在片段对象本身中,则一旦片段被破坏,数据将丢失。
要解决此问题,android会要求您使用Bundle
(调用setArguments()
)存储数据,然后可以从访问该数据YourFragment
。参数bundle
受Android保护,因此可以保证是持久的。
设置此捆绑包的一种方法是使用静态newInstance
方法:
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;
}
但是,构造函数:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
可以做和newInstance
方法完全一样的事情。
自然,这将失败,并且是Android希望您使用该newInstance
方法的原因之一:
public YourFragment(int data) {
this.data = data; // Don't do this
}
作为进一步的说明,这是Android的Fragment类:
/**
* 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;
}
请注意,Android要求仅在构造时设置参数,并保证将保留这些参数。
编辑:正如@JHH的注释中指出的那样,如果要提供需要一些参数的自定义构造函数,则Java不会为您的片段提供无arg默认构造函数。因此,这将需要您定义一个no arg构造函数,该代码可以通过newInstance
factory方法避免。
编辑:Android不允许再使用重载的构造函数来存储片段。您必须使用该newInstance
方法。