listview - FutureBuilder 只加载一次 API 数据

标签 listview flutter dart statefulwidget

我已经调用 post type api 使用 FutureBuilder 在 ListView 上异步加载数据,但它只调用了一次,我想在我的 ListView 上显示无限数据加载。

他们是否缺少添加 FutureBuilder 或 ListView 的一些属性。

谁能帮我解决这个问题,我是新手。

我正在使用有状态小部件来实现此功能。

请引用以下代码,

import 'package:flutter/material.dart';
import 'package:testlistviewlazyload/Utils.dart';
import 'package:testlistviewlazyload/ServiceManager.dart';
import 'package:testlistviewlazyload/Constant.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';

class ClassHome extends StatefulWidget {
  @override
  stateClassHome createState() => stateClassHome();
}

class stateClassHome extends State<ClassHome> {

  bool isLoading = false;

  List<dynamic> arrayFoodList = List<dynamic>();

  @override
  void initState() {
    super.initState();
  }


  Future<List<dynamic>> funcLoadMore() async{

      var dicArguments = {'restaurant_id': '3',
        'menu_id': '0',
        'offset': '0'
      };

     final dictResponse = await ServiceManager().callWebservice(
          enumMethodType.POST, ConstantApi.keyRestaurantMenuFoodList,
          dicArguments, {
        'Authorization':
        await Utils().funcGetSession(ConstantSession.keyAuthToken)
      }, 'tagRestaurantMenuFoodList');

      if (dictResponse['error'] == false) {
        if (dictResponse['mainResponse']['error'] == false) {

          return dictResponse['mainResponse']['data']['food_items']
          as List<dynamic>;

        } else {

          Utils()
              .funcDisplayAlertView(
              '', "${dictResponse['message']}", context);

        }
      } else {
        Utils().funcDisplayAlertView(
            '', "${dictResponse['message']}", context);
      }

  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        appBar: AppBar(title: Text('hello')),
        body: Container(
          color: Colors.pink[50],

          child: Column(

            children: <Widget>[

              Expanded(

                child: FutureBuilder<List<dynamic>>(
                     future: funcLoadMore(), // a previously-obtained Future<String> or null
                   builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {

                     List<dynamic> arrayTest = snapshot.data ?? [];

                      return Scrollbar(

                          child: ListView.builder(

                            itemCount: arrayTest.length,

                            itemBuilder: (BuildContext context, int index) {
                              return ListTile(
                                title: Text(arrayTest[index]['name']),
                              );
                            },

                          )
                      );
                     },
                ),


              ),

              Container(
                height: isLoading ? 50.0 : 0,
                color: Colors.white,
                child: Center(
                  child: new CircularProgressIndicator(),
                ),
              ),

            ],

          ),

        )

    );
  }
}

enter image description here

最佳答案

您可以使用 Stream 而不是 Future。这是一个通用示例,带有缓存和 scrollController当用户位于底部页面时获取下一个项目:

class _PageState extends State<Page> {
  int _count = 10;
  int _limit = 0;

  bool isLoading = false;

  List<Item> _cachedItems = List.from([]);

  StreamController<List<Item>> _streamController =
      StreamController<List<Item>>();
  StreamSink<List<Item>> get itemsSink => _streamController.sink;
  Stream<List<Item>> get itemsStream => _streamController.stream;

  ScrollController _scrollController = ScrollController();

  Future<void> _addItems() async {
    final params = {'count': '$_count', 'limit': '$_limit'};
    try {
      isLoading = true;
      // Fetch newItems with http
      isLoading = false;
      _cachedItems.addAll(newItems);
      itemsSink.add(_cachedItems);
      _limit += 10;
    } catch (e) {
      itemsSink.addError(e);
    }
  }

  _scrollListener() {
    if (_scrollController.offset >=
            _scrollController.position.maxScrollExtent &&
        !_scrollController.position.outOfRange &&
        !isLoading) {
      _addItems();
    }
  }

  @override
  void initState() {
    _scrollController.addListener(_scrollListener);
    super.initState();
  }

  @override
  void didChangeDependencies() {
    if (_cachedItems.isEmpty) _addItems();
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    _streamController.close();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Item>>(
        stream: itemsStream,
        builder: (context, snapshot) {
            ListView(
               controller: _scrollController,
               /// Build here your ListView
            ),
        }
      ),
    );
  }
}

关于listview - FutureBuilder 只加载一次 API 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60319972/

相关文章:

java - 更新 ListView 时如何更新 ListView 项目位置

android - 如何控制 ListView 重新加载。

flutter - 如何在不重新创建小部件的情况下重新渲染小部件-Flutter/Dart

python-3.x - 如何在Dart中使用参数和 header (Uri)发出HTTP请求

android - Flutter-如何使DatePicker中的选定值显示在TextFormField中?

c# - WPF Listview 交替行背景按数据组而不是行

ios - 如何使用 React Native iOS 将 ListView 放入 ScrollView 中?

dart - Web组件应该放在 "web"文件夹下吗?

firebase - Flutter:一个应用程序中有多个 firebase 项目,但显示的数据不正确

flutter - 如何在Dart中检查字符串为null?