我最近厌倦了在创建String
时不断知道Bundles
键将参数传递到Fragments
。所以我决定为我的Fragments
制作构造函数,它将获取我想要设置的参数,并将这些变量放入Bundles
并使用正确的String
键,因此无需其他Fragments
和Activities
需要知道这些密钥。
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);
}
然后我像平常一样提出这些论点。
@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对此提出了疑问,他说没有Fragment
的子类与带有其他参数的构造函数,要求我使用@SuppressLint("ValidFragment")
来运行应用程序。问题是,这段代码完全正常。我可以使用ImageRotatorFragment(int imageResourceId)
或旧学校方法ImageRotatorFragment()
并在其上手动调用setArguments()
。当Android需要重新创建片段(方向更改或低内存)时,它会调用ImageRotatorFragment()
构造函数,然后使用我的值传递相同的参数Bundle
,这些值已正确设置。
所以我一直在寻找“建议”的方法,并看到很多使用newInstance()
创建带有参数的Fragments
的例子,这似乎与构造函数的作用相同。所以我自己做了测试,它的工作方式和以前一样完美,减去Lint抱怨它。
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;
}
我个人发现使用构造函数比知道使用newInstance()
和传递参数更常见。我相信你可以使用相同的构造函数技术与活动和Lint不会抱怨它。 基本上我的问题是,为什么Google不希望您使用带Fragments
参数的构造函数?
我唯一的猜测是,你不要尝试在不使用Bundle
的情况下设置实例变量,Fragment
在重新创建static newInstance()
时不会被设置。通过使用public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
mImageResourceId = imageResourceId;
}
方法,编译器将不允许您访问实例变量。
{{1}}
我仍然觉得这不足以让我们不允许在构造函数中使用参数。其他人对此有所了解吗?
答案 0 :(得分:59)
我个人发现使用构造函数比使用newInstance()和传递参数更常见。
factory method pattern在现代软件开发中经常使用。
所以基本上我的问题是,为什么Google不希望你使用带有Fragments参数的构造函数?
你回答了自己的问题:
我唯一的猜测是,你不要尝试在不使用Bundle的情况下设置实例变量,在重新创建Fragment时不会设置它。
正确。
我仍然觉得这不足以让我们不允许在构造函数中使用参数。
欢迎您的意见。欢迎您以每个构造函数或每个工作区的方式禁用此Lint检查。
答案 1 :(得分:0)
Android只使用默认构造函数重新创建它杀死的片段,因此我们在其他构造函数中执行的任何初始化都将丢失。数据将丢失。