Android 为什么我想避免片段中的非默认构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12062946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do I want to avoid non-default constructors in fragments?
提问by BlackHatSamurai
I am creating an app with Fragments
and in one of them, I created a non-default constructor and got this warning:
我正在使用Fragments
其中一个创建一个应用程序,我创建了一个非默认构造函数并收到此警告:
Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead
Can someone tell me why this is not a good idea?
有人能告诉我为什么这不是一个好主意吗?
Can you also suggest how I would accomplish this:
你也可以建议我如何做到这一点:
public static class MenuFragment extends ListFragment {
public ListView listView1;
Categories category;
//this is my "non-default" constructor
public MenuFragment(Categories category){
this.category = category;
}....
Without using the non-default constructor?
不使用非默认构造函数?
采纳答案by nistv4n
Make a bundle object and insert your data (in this example your Category
object). Be careful, you can't pass this object directly into the bundle, unless it's serializable.
I think it's better to build your object in the fragment, and put only an id or something else into bundle. This is the code to create and attach a bundle:
创建一个包对象并插入您的数据(在本例中是您的Category
对象)。请注意,您不能将此对象直接传递到包中,除非它是可序列化的。我认为最好在片段中构建您的对象,并且只将一个 id 或其他东西放入包中。这是创建和附加包的代码:
Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);
After that, in your fragment access data:
之后,在您的片段访问数据中:
Type value = getArguments().getType("key");
That's all.
就这样。
回答by numan salati
It seems like none of the answers actually answer "why use bundle for passing parameters rather than non default constructors"
似乎没有一个答案真正回答“为什么使用 bundle 传递参数而不是非默认构造函数”
The reason why you should be passing parameters through bundle is because when the system restores a fragment
(e.g on config change), it will automatically restore your bundle
.
你应该通过 bundle 传递参数的原因是因为当系统恢复fragment
(例如配置更改)时,它会自动恢复你的bundle
.
The callbacks like onCreate
or onCreateView
should read the parameters from the bundle
- this way you are guaranteed to restore the state of the fragment
correctly to the same state the fragment
was initialised with (note this state can be different from the onSaveInstanceState bundle
that is passed to the onCreate/onCreateView
)
回调喜欢onCreate
或onCreateView
应该从bundle
-读取参数- 这样你就可以保证将fragment
正确的状态恢复到与fragment
初始化相同的状态(注意这个状态可能与onSaveInstanceState bundle
传递给的状态不同onCreate/onCreateView
)
The recommendation of using the static newInstance()
method is just a recommendation. You can use a non default constructor but make sure you populate the initialisation parameters in the bundle
inside the body of that constructor. And read those parameters in the onCreate()
or onCreateView()
methods.
使用静态newInstance()
方法的建议只是一个建议。您可以使用非默认构造函数,但请确保在该bundle
构造函数的主体内部填充初始化参数。并在onCreate()
oronCreateView()
方法中读取这些参数。
回答by Asaf Pinhassi
Your Fragment
shouldn't have constructors because of how the FragmentManager
instantiates it.
You should have a newInstance()
static method defined with the parameters you need, then bundle them and set them as the arguments of the fragment, which you can later access with the Bundle
parameter.
你Fragment
不应该有构造函数,因为它是如何FragmentManager
实例化的。您应该newInstance()
定义一个静态方法,其中包含您需要的参数,然后将它们捆绑并设置为片段的参数,您可以稍后使用Bundle
参数访问这些参数。
For example:
例如:
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 ;
}
And read these arguments at onCreate
:
并在onCreate
以下位置阅读这些参数:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
title = getArguments().getInt(EXTRA_TITLE);
message = getArguments().getString(EXTRA_MESSAGE);
//...
}
This way, if detached and re-attached, the object state can be stored through the arguments, much like bundles
attached to Intent
s.
这样,如果分离并重新附加,则可以通过参数存储对象状态,就像bundles
附加到Intent
s 一样。
回答by ???
If you use parameter for some class. try this
如果您对某个类使用参数。尝试这个
SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
MyFragment f = new MyFragment();
f.mSomeInstance = someInstance;
return f;
}
回答by Pavlus
I think, there is no difference between static constructor and two constructors (empty and parametrized one that stores arguments into a Fragment's arguments bundle), most probably, this rule of thumb is created to reduce probability of forgetting to implement no-arg constructor in Java, which is not implicitly generated when overload present.
我认为,静态构造函数和两个构造函数(将参数存储到 Fragment 的参数包中的空和参数化构造函数)之间没有区别,最有可能的是,创建此经验法则是为了减少忘记在 Java 中实现无参数构造函数的可能性,当存在过载时不会隐式生成。
In my projects I use Kotlin, and implement fragments with a primary no-arg constructor and secondary constructor for arguments which just stores them into a bundle and sets it as Fragment arguments, everything works fine.
在我的项目中,我使用 Kotlin,并使用主要的无参数构造函数和辅助构造函数为参数实现片段,这些参数只是将它们存储到一个包中并将其设置为片段参数,一切正常。
回答by Akop Vardanian
If fragment uses non-default constructors after configuration changing the fragment will lose all data.
如果片段在配置更改后使用非默认构造函数,片段将丢失所有数据。