
5.1 使用ListView创建滚动列表
首先解决App中的第一个问题,在News小部件中,我们尝试使用Column小部件来渲染一个列表,Column可以拥有多个子部件,可以使用news列表,通过map()方法转换成一组小部件,然后赋值给Column中的children参数。我们返回的是一些Card。这些Card可以被渲染到屏幕上,但问题是添加更多的Card时会报错,而且不能滚动,如图5.1所示。

图5.1 添加更多的news时报错
Flutter尝试在一个页面加载它们,发现空间不足,所以这里不应该使用Column小部件。如果想实现一些元素彼此是上下排列的,从上到下渲染,并且不打算使用滚动功能,那么Column是一个很好的选择。但是在这个例子中,页面中存在多个Card小部件,它们可能会超越屏幕的边界,Column就不是正确的选择了。
但是有一个小部件能够满足这个例子的要求,它叫ListView。ListView是一个渲染列表的小部件,它也有children参数需要传入一组小部件,用ListView替换Column,保存并重启,代码如下:

在IDE中显示了错误信息,如图5.2所示。

图5.2 IDE中的错误信息
这是一个含糊不清的错误提示,实际上提示的是ListView不能在按钮下面使用,在news_manager.dart文件中,代码如下:

ListView是在一个按钮下面使用的,ListView的上面是一个Container包装的按钮,在Flutter中不能这样用。如果在Column中创建了一个Container或其他组件,然后在这个小部件下面使用ListView,需要把这个ListView也包装成另外一个Container,所以这里需要把ListView赋值给Container的child。同时需要设置Container的高度,定义Container的大小。代码如下:

我们把它的高度设置为300.0。保存之后,可以看到列表显示出来了,单击按钮可以添加新的Card,但是Container只有300像素的高度,如图5.3所示。

图5.3 ListView所在的Container的高度
如果想使用余下所有的可用空间,可以先把height删除,再把Container替换成另外一个小部件Expanded。Expanded小部件可以使用按钮下面的剩余可用空间,代码如下:

现在这个列表可以上下滚动,这样就实现了一个可以滚动的List。如果添加更多的Card,就可以滚动显示了,而且不报错,然而如果在这里快速添加多个Card,导致这个小部件频繁被调用,就会产生性能问题,所以要做一些事情来避免这样的问题,因为事先我们并不知道news的确切数量。下一节学习如何提升列表的性能。