使用 RefreshIndicator 时,无法将参数类型 'Future<List<User>>' 分配给 onRefresh 中的参数类型 'Future<void> Function()'

The argument type 'Future<List<User>>' can't be assigned to the parameter type 'Future<void> Function()' in onRefresh when using RefreshIndicator

我有一个 Future 正在获取和填充下面的用户

Future<List<User>> _fetchUsersListUsingLoop() async {
    try {
      
      var response = await http.get(
          Uri.parse(
              "https://api.json-generator.com/templates/Eh5AlPjYVv6C/data"),
          headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer tltsp6dmnbif01jy9xfo9ssn4620u89xhuwcm5t3",
          });


      List<User> usersList = [];

      for (var u in json.decode(response.body)) {
        User user = User(u["email"], u["about"], u["name"], u["picture"],
            u["index"], u["imageFetchType"]);

        usersList.add(user);
      }

      return usersList;
    } catch (e) {
      log("FetchUsersListUsingLoopException $e");

      rethrow;
    }
  }

下面是我如何在 FutureBuilder 中使用 future 调用 _fetchUsersListUsingLoop() 然后使用 ListView.builderRefreshIndicator 中显示 list

中的用户
body: SizedBox(
        child: FutureBuilder(
            future: _fetchUsersListUsingLoop(),
            builder: (BuildContext context, AsyncSnapshot asyncSnapshot) {
              if (asyncSnapshot.data == null) {
                return const Center(child: CircularProgressIndicator());
              } else {
                return RefreshIndicator(
                  // background color
                    backgroundColor: Colors.white,
                    // refresh circular progress indicator color
                    color: Colors.green,
                    onRefresh: _fetchUsersListUsingLoop(),
                    child: ListView.builder(
                      itemCount: asyncSnapshot.data.length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          contentPadding: const EdgeInsets.all(10),
                          leading: CircleAvatar(
                            backgroundImage:
                                NetworkImage(asyncSnapshot.data[index].picture),
                          ),
                          title: Text(asyncSnapshot.data[index].name),
                          subtitle: Text(
                              "${asyncSnapshot.data[index].email} \nUsing NetworkImage with backgroundImage"),
                        );
                      },
                    ));
              }
            }),
      ),

我在这一行中收到 The argument type 'Future<List<User>>' can't be assigned to the parameter type 'Future<void> Function()'. 错误 onRefresh: _fetchUsersListUsingLoop(), 当我向下滑动以刷新

时如何才能再次调用 _fetchUsersListUsingLoop()

不应调用 _fetchUsersListUsingLoop,而应使用 setState 进行重建,以便 FutureBuilder 再次获取数据。

onRefresh: () => setState(() {})

据说最好将您的未来存储在 initState 中,并在需要时通过调用 setState 更新此未来。这是来自 documentation:

The future must have been obtained earlier, e.g. during State.initState, State.didUpdateWidget, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.

Future<List<User>>? _usersFuture;

@override
  void initState() {
    super.initState();
    _usersFuture = _fetchUsersListUsingLoop();
}

然后:

onRefresh: () {
    setState(() {
      _usersFuture = _fetchUsersListUsingLoop();
    });
  }

当你这样做时

onRefresh: _fetchUsersListUsingLoop(),

你告诉 dart 调用 _fetchUsersListUsingLoop 并期望它成为 return 一个函数,然后调用所述函数,你想要做的是告诉它只调用 _fetchUsersListUsingLoop:

onRefresh: _fetchUserListUsingLoop,

or ìf 那行不通:

onRefresh: () async => _fetchUserListUsingLoop(),

但问题是这实际上行不通,为什么?因为 future builder 已经完成并且不会改变它来解决您的问题;你可以像这样重新分配未来:

您需要声明一个未来:

late Future<List<User>> _user;
        child: FutureBuilder(
            future: _users,
            builder: (context, asyncSnapshot) {
              ...
                    onRefresh: _updateUsersFuture,
              ...

然后在你 class 的某处你做:

Future<void> _updateUsersFuture() async {
  final newUsers = await _fetchUserListUsingLoop();
  setState(() => _users = newUsers);
}

和初始化状态:

@override
void initState() {
  _users = _fetchUsersListUsingLoop();
  super.initState();
}