ListView

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

填充固定内容

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

ListView(
  children: <Widget>[
    ListTile(
      title: Text('我要发布'),
      trailing: Icon(Icons.send),
    ),
    Divider(),
    ListTile(
      title: Text('注销'),
      trailing: Icon(Icons.exit_to_app),
    )
  ]
)

循环渲染列表数据

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

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

保持列表项的数据状态

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

class _MovieListState extends State<MovieList>
    with AutomaticKeepAliveClientMixin {
      // 重写 wantKeepAlive 函数
      @override
      bool get wantKeepAlive => true;
    }

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

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

// 定义私有变量 _scrollCtrl
ScrollController _scrollCtrl;

// 重写 initState 生命周期函数
@override
void initState() {
  // 此行为默认代码,不能删除
  super.initState();
  // 初始化一个 ScrollController 滚动控制器
  _scrollCtrl = new ScrollController();
  // 为 _scrollCtrl 滚动控制器添加监听事件
  _scrollCtrl.addListener(() {
    // _scrollCtrl.position.pixels 当前列表滚动的距离
    // _scrollCtrl.position.maxScrollExtent 列表的最大滚动距离
    if (_scrollCtrl.position.pixels == _scrollCtrl.position.maxScrollExtent) {
      // 调用 setState 函数,让页码值 +1
      setState(() {
        _page++;
      });
      // 获取新页面的数据
      _getMovieList();
    }
  });
}

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

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

ListView.builder(
  controller: _scrollCtrl,
  itemCount: _mlist.length,
  itemBuilder: (BuildContext ctx, int i) {}
)

清理滚动控制器

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

// 重新 dispose 函数
@override
void dispose() {
  super.dispose();
  // 主动销毁滚动控制器
  _scrollCtrl.dispose();
}

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

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

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

results matching ""

    No results matching ""