潜在无限项目的列表:ListView.builder,StreamBuilder,FutureBuilder或其他?

时间:2020-07-29 06:57:59

标签: flutter dart

我需要开发从服务器加载的潜在无限项目的列表。当用户到达列表末尾时,必须加载其他项目。
我正在寻找一个网络,以了解如何最好地做到这一点。

这是我发现的:

ListView.builder和一个ScrollController,可在结束时加载新项目,其代码如下:

if (_controller.position.pixels == _controller.position.maxScrollExtent) {
  // load other items
}

这种方法的问题是我必须保存从服务器加载的最后一页,以免再次加载相同的项目。

我还找到了StreamBuilderFutureBuilderPaginatedDataTable,但是我不确定它们是否是管理无限列表的正确小部件。
解决此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

我有一种非常有趣的技术,向您展示如何以最佳的方式实现所需的结果。

免责声明

  • 我已使用我的数据集来显示如何将列表添加新数据,而不是重复的数据
  • 我已经演示了单击按钮时追加的数据,要查看底部即将出现的数据,可以使用scrollController。您可以在_loadMore()
  • 中进行操作

想法

  • 我们维护two lists,一个是原始的,另一个跟踪添加新数据。名称为originalListitems
  • 我们使用两个变量,一个是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;
    });
  }
}

结果

Result data