Flutter实战指南
上QQ阅读APP看书,第一时间看更新

2.15 给StatefulWidget传递参数

StatelessWidget怎样从外部接收数据呢?在NewsManager小部件中,数组中的first使用的是硬编码。现在我们想从外部获得NewsManager的初始化数据,可以在main.dart中给NewsManager小部件传数据。可以像News小部件那样通过参数传递数据,然后通过构造器方法接收数据。在NewsManager中也可以这样做。在NewsManager添加构造器、类名括号,代码如下:

构造器现在可以接收一个参数startingNews,同样使用了this加点这种快捷方式来赋值。加上final表示startingNews是从外部获取的,改变startingNews的唯一办法是在它的父级小部件中重新创建NewsManager小部件,这个过程会传入一个新值给startingNews,然后NewsManager的属性会重新被赋值。

现在的问题是如何使用startingNews,我们在NewsManager中获取到这个值了,但是需要在_NewsManagerState中使用它。现在你可能会有一个想法,通过构造器把这个值传入到_NewsManagerState中,然后保存。这样做没问题,但是非常麻烦,这不是一个好方法。Flutter提供了一个非常有用的关键字widget,它允许你访问这个状态对应的小部件中的所有属性。因为之前了解到NewsManager和_NewsManagerState是连接在一起的。Flutter为我们做了一些幕后工作,通过关键字widget可以访问连接的小部件的属性,例如这里的NewsManager类中的startingNews。

注意不可以在类中初始化属性,只能在_NewsManagerState类的方法中使用widget获取NewsManager的属性。Flutter中的State类允许实现一些特别的方法,例如initState()方法,输入initState时IDE会有提示。initState()是一个覆盖的方法。代码如下:

图2.22 模拟器显示结果

super代表扩展的基类,这里代表State类,super.initState();这样写保证在基类中initState()方法会被调用,所以不可以删除它。State类创建的时候会调用initState()初始化方法。可以认为是在NewsManager小部件第一次显示在屏幕上时initState()方法被调用,所以这里可以使用news.add(widget.startingNews);表示使用了NewsManager中的startingNews了,并把它添加到news数组中。因为initState()方法在_NewsManagerState创建时被执行,所以在第一次运行_NewsManagerState中的build()方法时,初始化方法initState()已经被执行了。

在main.dart文件中给NewsManager传递值,例如first,代码如下:

     body: NewsManager('first)',//创建NewsManager并传值first

保存,重启会发现first这条资讯显示到模拟器上了,这意味着逻辑生效了,如图2.22所示。