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

时间:2012-08-21 20:57:50

标签: android android-fragments

我正在使用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;
    }....

不使用非默认构造函数?

6 个答案:

答案 0 :(得分:226)

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

您应该通过bundle传递参数的原因是,当系统恢复fragment时(例如,在配置更改时),它将自动恢复您的bundle

onCreateonCreateView等回调应该从bundle读取参数 - 这样您就可以保证将fragment的状态正确恢复到同一状态fragment已初始化(注意此状态可能与传递给onSaveInstanceState bundle的{​​{1}}不同)

使用静态onCreate/onCreateView方法的建议只是一个建议。您可以使用非默认构造函数,但请确保在该构造函数体内的newInstance()中填充初始化参数。并在bundleonCreate()方法中阅读这些参数。

答案 1 :(得分:105)

创建一个bundle对象并插入你的数据(在这个例子中是你的Category对象)。请注意,除非可以序列化,否则您无法将此对象直接传递到捆绑包中。 我认为在片段中构建对象更好,并且只将id或其他东西放入bundle中。这是创建和附加包的代码:

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

之后,在您的片段访问数据中:

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

这就是全部。

答案 2 :(得分:46)

由于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);

    //...
}

这样,如果分离并重新附加,则可以通过参数存储对象状态,就像附加到bundles的{​​{1}}一样。

答案 3 :(得分:12)

如果您为某个类使用参数。试试这个

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

答案 4 :(得分:1)

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

在我的项目中,我使用Kotlin,并使用主要的无参数构造函数和辅助构造函数实现片段,这些参数只是将它们存储到一个包中并将其设置为Fragment参数,一切正常。

答案 5 :(得分:0)

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