为什么有状态小部件被定义为flutter中的两个类?

时间:2018-05-30 19:36:27

标签: generics dart flutter

我是新手扑动/飞镖,所以当我尝试制作应用程序时,我也试着理解为什么事情是某种方式。在flutter文档中,有一个有状态小部件的示例代码如下所示:

class YellowBird extends StatefulWidget {
  const YellowBird({ Key key }) : super(key: key);

  @override
  _YellowBirdState createState() => new _YellowBirdState();
}

class _YellowBirdState extends State<YellowBird> {
  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFFFFE306));
  }
}

问题:

  1. 为什么他们用两个类而不是一个类定义?我猜测State类可以在其他地方使用,所以最好分开。

  2. 根据我的理解,createState()函数返回State类型的对象,因此_YellowBirdState extends State有意义,但为什么YellowBird会传入通用State的等级?我的猜测它与Yellowbird扩展StatefulWidget类有关但不太确定。

4 个答案:

答案 0 :(得分:14)

有多种原因:

  • 小部件是不可变的。由于StatefulWidget扩展Widget,因此它也必须是不可变的。将声明拆分为两个类允许StatefulWidget是不可变的,State是可变的。

  • 使用语法new MyWidget()实例化窗口小部件。如果我们将两个类合并为一个,new MyWidget()将在每次父更新时重置该状态的所有属性。

关于class _MyStatefulState extends State<MyStateful>

的解释

这是因为State班级可以使用Stateful字段访问this.widget部分。 这里的通用名称是MyStateful类型的字段,而不仅仅是StatefulWidget。您可能想要访问MyStateful属性。

答案 1 :(得分:11)

  1. Flutter的主要设计决策之一是重新创建小部件很便宜,因此可以调用build()来重建小部件树的分支。这对于通过构造函数赋予其不可变值的无状态小部件非常有效。但有状态的小部件需要在构建之间保留它们的状态。在您的示例中,框架可以创建多个YellowBird,但它只创建一个YellowBirdState。每个新创建的YellowBird都可以通过框架透明地连接到现有的YellowBirdState

  2. State的子类需要知道其Widget类型,以便编译器知道变量widget的类型。在YellowBirdState中,您可以使用widget来引用窗口小部件。如果YellowBird具有成员变量final String foo,则编译器知道widget.fooYellowBird中名为foo的字符串。

答案 2 :(得分:1)

类YellowBird扩展了StatefulWidget

StatefulWidget是一个不可变的类(不可变的类表示一旦创建对象,我们就无法更改其值)。 1-必须将课程声明为最终课程(这样才能创建子课程) 2-必须将类中的数据成员声明为最终成员(这样我们才能更改该值 创建对象后) 3-参数化的构造函数 4-Getter方法用于其中的所有变量。没有二传手(没有选择权可以改变 实例变量的值)

类别_YellowBirdState扩展了状态

类型为通用的状态类是一个可变的类,在创建其对象后可以用不同的值实例化。


与此不可更改的StatefullWdget类相同,它正在调用createState()函数,该函数在窗口小部件被打动后定义窗口小部件的状态State 因此我们可以通过这种方法一次又一次地更改小部件的值,但不能更改有状态或无状态的类型。

答案 3 :(得分:0)

Flutter documentation 解释了这一点。

<块引用>

拥有单独的状态和小部件对象可以让其他小部件以完全相同的方式处理无状态和有状态小部件,而不必担心丢失状态。父级可以随时创建子级的新实例,而无需保留子级以保持其状态,而不会丢失子级的持久状态。该框架会在适当的时候完成查找和重用现有状态对象的所有工作。

基本上,它使有状态小部件可以重新实例化(无论何时build(),例如从状态更改)而不会丢失其状态。

这也是由 Widget 不可变强制执行的,因此可变状态数据必须存储在其他地方:State 对象。