我需要开发从服务器加载的潜在无限项目的列表。当用户到达列表末尾时,必须加载其他项目。
我正在寻找一个网络,以了解如何最好地做到这一点。
这是我发现的:
ListView.builder
和一个ScrollController
,可在结束时加载新项目,其代码如下:
if (_controller.position.pixels == _controller.position.maxScrollExtent) {
// load other items
}
这种方法的问题是我必须保存从服务器加载的最后一页,以免再次加载相同的项目。
我还找到了StreamBuilder
,FutureBuilder
和PaginatedDataTable
,但是我不确定它们是否是管理无限列表的正确小部件。
解决此问题的最佳方法是什么?
答案 0 :(得分:2)
我有一种非常有趣的技术,向您展示如何以最佳的方式实现所需的结果。
免责声明
scrollController
。您可以在_loadMore()
想法
two lists
,一个是原始的,另一个跟踪添加新数据。名称为originalList
和items
。perPageItems
,用于根据意愿显示项目,而presentItems
用于维护到目前为止加载的数据量。它以0
items
按照代码进行,为了您的方便,我添加了大多数注释。希望你能得到最终结果
class _MyHomePageState extends State<MyHomePage> {
int perPageItems = 15;
int presentItems = 0;
List<String> items = List<String>();
List<String> originalItems = new List.generate(100, (index) => 'Hello $index');
@override
void initState() {
super.initState();
// copying the data source to the other list
items.addAll(originalItems.getRange(presentItems, presentItems + perPageItems));
// updating the present Items now, since it has perPageItems now in the page
presentItems = presentItems + perPageItems;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Scrollbar(
child: new ListView.builder(
itemBuilder: (context, index) {
// to check whether we have reached to the
// the last page, which is the last item
// as per the page count which is 15
return (index == items.length ) ?
Container(
color: Colors.greenAccent,
child: FlatButton(
child: Text("Load More"),
onPressed: () => _loadMore(),
),
) : ListTile(
title: Text('${items[index]}'),
);
},
// Here in the code itemCount if present i.e.,
// no of items loaded is lessthan or equal to total no of items
// in original list then we return +1 so we can add LoadMore
// else we return the size of the list
itemCount: (presentItems <= originalItems.length) ? items.length + 1 : items.length
)
),
);
}
// Here in the code if present + perPage will become new final no of
// list to be loaded is greater then out complete original list
// length then we pass originalItems.length in the getRange else we
// pass present + perPage in getRange
void _loadMore() {
setState(() {
if((presentItems + perPageItems) > originalItems.length) {
items.addAll(
originalItems.getRange(presentItems, originalItems.length));
} else {
items.addAll(
originalItems.getRange(presentItems, presentItems + perPageItems));
}
presentItems = presentItems + perPageItems;
});
}
}
结果