ListView

滚动列表,可以很单纯中填充固定个数的内容,也可以循环渲染列表数据。

填充固定内容

用法最简单,将需要的内容节点,直接写入到 ListView 组件的 children 属性中即可,代码示例如下:

  1. ListView(
  2. children: <Widget>[
  3. ListTile(
  4. title: Text('我要发布'),
  5. trailing: Icon(Icons.send),
  6. ),
  7. Divider(),
  8. ListTile(
  9. title: Text('注销'),
  10. trailing: Icon(Icons.exit_to_app),
  11. )
  12. ]
  13. )

循环渲染列表数据

如果要把列表数据,通过循环渲染之后,得到 UI 结构类似的列表页面,推荐使用 ListView.builder(),基础用法如下:

  1. ListView.builder(
  2. // 必须指定列表项的长度
  3. itemCount: 列表项的长度,
  4. // Item 项的构建器
  5. itemBuilder: (BuildContext ctx, int i) {
  6. return Text('aaa');
  7. }
  8. )

保持列表项的数据状态

如果存在多个列表页之间的动态切换,默认无法保持每个列表项的滚动距离、数据状态等信息,此时需要实现 AutomaticKeepAliveClientMixin 特征,来保持列表项的滚动状态,示例代码如下:

  1. class _MovieListState extends State<MovieList>
  2. with AutomaticKeepAliveClientMixin {
  3. // 重写 wantKeepAlive 函数
  4. @override
  5. bool get wantKeepAlive => true;
  6. }

监听列表是否滚动到页面底部

有时候,需要实现列表滚动到页面底部之后,自动加载下一页数据,此时需要借助于 ScrollController 实现滚动监听,示例代码如下:

  1. // 定义私有变量 _scrollCtrl
  2. ScrollController _scrollCtrl;
  3. // 重写 initState 生命周期函数
  4. @override
  5. void initState() {
  6. // 此行为默认代码,不能删除
  7. super.initState();
  8. // 初始化一个 ScrollController 滚动控制器
  9. _scrollCtrl = new ScrollController();
  10. // 为 _scrollCtrl 滚动控制器添加监听事件
  11. _scrollCtrl.addListener(() {
  12. // _scrollCtrl.position.pixels 当前列表滚动的距离
  13. // _scrollCtrl.position.maxScrollExtent 列表的最大滚动距离
  14. if (_scrollCtrl.position.pixels == _scrollCtrl.position.maxScrollExtent) {
  15. // 调用 setState 函数,让页码值 +1
  16. setState(() {
  17. _page++;
  18. });
  19. // 获取新页面的数据
  20. _getMovieList();
  21. }
  22. });
  23. }

为 ListView 组件添加 controller 滚动控制器

如果想监听 ListView 组件的滚动效果,可以为 ListView.builder() 提供 controller 属性,值为 ScrollController 的示例对象,示例代码如下:

  1. ListView.builder(
  2. controller: _scrollCtrl,
  3. itemCount: _mlist.length,
  4. itemBuilder: (BuildContext ctx, int i) {}
  5. )

清理滚动控制器

当页面被销毁的时候,最好主动销毁对应的滚动控制器,主动释放内存,提高性能:

  1. // 重新 dispose 函数
  2. @override
  3. void dispose() {
  4. super.dispose();
  5. // 主动销毁滚动控制器
  6. _scrollCtrl.dispose();
  7. }

获取下一页数据后合并数组

如果分页加载数据,则应该让旧数组主动拼接新数组,代码示例如下:

  1. setState(() {
  2. _total = result.data['count'];
  3. // 调用数组的 addAll 方法,可以主动合并另一个数组
  4. _mlist.addAll(result.data['subjects']);
  5. });