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']);
});