不包含所有成员的 Flutter Stateful Widget 构造函数

Flutter Stateful Widget Constructor That Does Not Include All Members

我正在 Flutter 中构建一个 Stateful Widget,因此,要求构造函数中传递的所有参数都是最终的(因为 Stateful widget 标有 @immutable 注释)。

事实是,我希望我的小部件有两个不同的构造函数,并根据所使用的构造函数排除有状态小部件的一些成员。我必须强调,我不希望这些参数是可选的,而是强制性的。

例如,

class MyWidget extends StatefulWidget {
     
  MyWidget.first({this.firstArgument}};

  MyWidget.second({this.secondArgument});

  final int firstArgument;
  final String secondArgument;

  @override
  MyWidget createState() => MyWidgetState();
}

当我写这个的时候,我得到一个编译器错误,告诉我:

All final variables must be initialized, but 'firstArgument' isn't.

第二个成员变量同理

我该如何克服这个问题?

我不能将 firstArgumentsecondArgument 移动到 MyWidget 的状态,因为我希望它们在构造函数中初始化,也因为它们不应该被更改。 我无法将它们标记为非最终版本,因为那时我会收到编译器警告并破坏有状态小部件范例。

我应该使用其他方法吗?

也许 factory 构造器会有所帮助?

    class MyWidget extends StatefulWidget {
         
      MyWidget._({this.firstArgument, this.secondArgument}};
    
      factory MyWidget.first({@required int first})=>MyWidget._(firstArgument: first, );
      factory MyWidget.second({@required String second})=>MyWidget._(secondArgument: second, );
      final int firstArgument;
      final String secondArgument;
    
      @override
      MyWidget createState() => MyWidgetState();
    }

这样,您将只能使用这些构造函数构建此小部件(因为 class 构造函数是私有的)并且当您调用 MyWidget.first 时 的值小部件的 secondArgument 将为空,当您将 MyWidget.second 与 firstArgument

一起使用时同样适用

Thing is, I want to have two different constructors for my widget and to exclude some of the members of the Stateful widget, depending on the constructor used. I have to stress, that I do not want these arguments to be optional, but mandatory.

如果不希望它们是可选的,则需要将它们标记为必需:

  MyWidget.first({required this.firstArgument}};

  MyWidget.second({required this.secondArgument});

(如果您没有启用 null-safety,则需要使用 package:meta 中较弱的 @required 注释。)

我的理解是,您希望 firstArgumentsecondArgument 分别是 MyWidget.firstMyWidget.second 所必需的,但它们并不是必需的 一起(即只设置一个)。

您可以通过在构造函数中显式初始化两个值来解决此问题:

  MyWidget.first({required this.firstArgument}} : secondArgument = null;
  MyWidget.second({required this.secondArgument}): firstArgument = null;

如果您启用了空安全,您还需要让您的成员可以为空:

  final int? firstArgument;
  final String? secondArgument;