当前位置: 首页 > 知识库问答 >
问题:

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

唐阳飙
2023-03-14

我正在创建一个带有片段的应用程序,在其中一个片段中,我创建了一个非默认构造函数,并收到以下警告:

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;
    }....

不使用非默认构造函数?

共有3个答案

谭浩皛
2023-03-14

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

    //...
}

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

龙亮
2023-03-14

创建一个bundle对象并插入您的数据(在本例中为您的类别对象)。请注意,您不能将此对象直接传递到bundle中,除非它是可序列化的。我认为最好在片段中构建您的对象,并将一个id或其他东西放入bundle中。这是创建和附加bundle的代码:

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

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

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

仅此而已。

漆雕正奇
2023-03-14

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

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

onCreateonCreateView这样的回调应该从bundle中读取参数-这样您就可以保证将片段的状态正确恢复到片段初始化时使用的相同状态(注意此状态可能不同于传递给onCreate/onCreateViewonSaveInstanceState bundle

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

 类似资料:
  • 问题内容: 通常我会尽可能避免转换类型,因为我认为这是不良的编码实践,并且可能会导致性能下降。 但是,如果有人要我解释为什么会这样,我可能会像前灯中的鹿一样看它们。 那么,为什么/何时铸造不好? 它对于Java,C#,C ++是通用的,还是每个不同的运行时环境都按照自己的方式处理? 欢迎使用任何语言的细节,例如为什么在c ++中不好? 问题答案: 您已经用三种语言标记了这三种语言,答案在三种语言之

  • 问题内容: 除了* 使用如下所示的反射检查 之外 ,是否有任何方法 要求 类具有默认(无参数)构造函数?(以下方法可以工作,但是很hacky,反射速度很慢) * 问题答案: 您可以为此构建一个注释处理器。注释处理器是在编译时运行的编译器插件。它们的错误显示为编译器错误,甚至可能停止构建。 这是一个示例代码(尽管我没有运行它): 如果引入注释(例如RequiresDefaultAnnotation)

  • 问题内容: 我是一名Java初学者,了解以下Java编译器规则: 如果该类没有超类,则将其扩展到Object类 如果该类没有构造函数,请添加默认的无参数构造函数 如果构造函数的第一行不是“ super()”或“ this()”,请添加“ super()”以调用超类的默认构造函数。 我知道我们创建的所有对象都是从超类Object派生的。我的问题是被调用时Object类中的构造函数做什么? 编辑:我的

  • 问题内容: 我知道我在这里问一些严重的101问题… 我有一些课,还有一个延伸课。在我有一个构造函数,它接受一组参数,并对其字段进行设置。派生类(例如)通常不需要进行修改。现在我的IDE给我 “ Foo中没有默认的构造函数” 。从一点点谷歌搜索,这似乎是因为“构造函数没有继承”。因此,一切都很好,但是我现在如何使它工作而不在每个派生类中复制此构造函数?我假设有一个更合理的方法? 问题答案: 使用构造

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 在C#中,当我创建一个空类时,它提供了一个默认的构造函数,但是当我提供一个带有参数的构造函数时,默认的构造函数不再被创建。 我的问题是: 为什么编译器不再给我默认的构造函数呢 这些问题来自于WCF,我需要默认构造函数,但也希望能够为构造函数提供值,并且不必每次都放置默认构造函数,而且我不认为未使用的默认构造函数会使很多开销。