来自 webservice 的元素不会出现在 Flutter 的拖放列表中

Elements from webservice doesn't appear in Drag and drop List in Flutter

我已经用静态数据构建了一个拖放列表,效果很好,现在当我尝试从网络服务添加数据时,它没有显示在小部件中(它只显示静态数据):

但与此同时,当我在控制台中对列表执行 print() 操作时,它会显示所有数据(静态数据和来自网络服务的数据):

这是我的代码:

class Taches extends StatefulWidget{
  @override
  TachesState createState(){
    return new TachesState();
  }
}
class TachesState extends State<Taches> {

  //the static data
  List<String> listeTaches = [
    'Tâche 1',
    'Tâche 2',
    'Tâche 3',
    'Tâche 4',
    'Tâche 5',
    'Tâche 6',
    'Tâche 7',
    'Tâche 8',
    'Tâche 9',
    'Tâche 10',
  ];

  void getTaches() async {
    Session session = new Session();
    var taches = jsonDecode(await session.authentification());
    //here I add the data from the webservice
    for(int i = 0; i < taches['result']["inRangeTasks"].length ; i++){
      var tacheStr = taches['result']["inRangeTasks"][i]['name'];
      listeTaches.add(tacheStr.toString());
    }
    print(listeTaches);
  }

  _onReorder(oldIndex, newIndex) {
    setState((){
      if(newIndex > oldIndex){
        newIndex -= 1;
      }
      var item = listeTaches.removeAt(oldIndex);
      listeTaches.insert(newIndex, item);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: NavDrawer(),
      appBar: AppBar(
        title: Text('Beotic Project'),
        centerTitle: true,
      ),
      body: ReorderableListView(
            header: Center(
              child: Container(
                child: Text(
                  'Listes des tâches',
                  style: Theme.of(context).textTheme.headline5,
                ),
                padding: EdgeInsets.symmetric(vertical: 20)
              )
            ),
            children: listeTaches.map((e) => ListTile(
                key: UniqueKey(),
                leading: Icon(Icons.task),
                title: Text(e),
                trailing: Icon(Icons.more_vert),
              )).toList(), 
            onReorder: _onReorder,
      ),
    );
  }

  @override
  void initState(){
    //I directly call, in the initState function, the function which extract the data from the webservice and put it in the list
    getTaches();
  }
}

我的目标是让列表中的所有数据都显示在小部件上,

可能是我做错了什么,

感谢您的帮助!

你的代码的问题在于,虽然 getTaches() 是一个 async 函数,但你不能 await 它在 initState 中,因为 initState不能是异步函数。因此,您的 ReorderableListView 将在数据返回并添加到 getTaches() 函数中的 listeTaches 之前构建。

解决方案是使用 FutureBuilder,并且仅在 future(获取)完成后才构建小部件。检查以下代码。我简化了它并模拟了延迟和后端调用,但您可以看到它是如何工作的并根据您的需要进行调整。

import 'package:flutter/material.dart';

void main() => runApp(
      const MaterialApp(
        home: Scaffold(body: Taches()),
      ),
    );

class Taches extends StatefulWidget {
  const Taches({Key? key}) : super(key: key);
  @override
  TachesState createState() => TachesState();
}

class TachesState extends State<Taches> {
  //the static data
  List<String> listeTaches = [
    'Tâche 1',
    'Tâche 2',
    'Tâche 3',
    'Tâche 4',
    'Tâche 5',
    'Tâche 6',
    'Tâche 7',
    'Tâche 8',
    'Tâche 9',
    'Tâche 10',
  ];

  Future<List<String>> getTaches() async {
    return Future.delayed(const Duration(milliseconds: 2000), () {
      for (int i = 11; i <= 20; i++) {
        listeTaches.add('Tâche $i');
      }
      return listeTaches;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: FutureBuilder<List<String>>(
                future:
                    getTaches(), // a previously-obtained Future<String> or null
                builder: (BuildContext context,
                    AsyncSnapshot<List<String>> snapshot) {
                  if (snapshot.hasError) {
                    // manage error
                    return const Text('Error');
                  }
                  // no error and we have data
                  if (snapshot.hasData) {
                    return ReorderableListView(
                      header: Center(
                          child: Text(
                        'Listes des tâches',
                        style: Theme.of(context).textTheme.headline5,
                      )),
                      children: listeTaches
                          .map((e) => ListTile(
                                key: UniqueKey(),
                                leading: const Icon(Icons.task),
                                title: Text(e),
                                trailing: const Icon(Icons.more_vert),
                              ))
                          .toList(),
                      onReorder: (oldIndex, newIndex) => {},
                    );
                  }
                  // show initial data while loading
                  return const Center(child: CircularProgressIndicator());
                })));
  }
}