首页 > 解决方案 > Flutter/Dart:获取目录内容但未来不工作

问题描述

我正在尝试获取目录的内容并将其显示在屏幕上。

当我只有 1 个未来(并在方法中硬编码返回值)时,我能够显示它们。但是当我在未来中嵌入未来时(我需要这样做以获取应用程序目录和文件列表),它不起作用。

这是我的代码:

  Future<List<CardFileInfo>> _getFilelist() {
    var localFileHelper = new LocalFileHelper();
    return Future.value(localFileHelper.getFileList());
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("Cards")
      ),
       body: Center(
         child: Column(
           children: <Widget>[
             FutureBuilder<List<CardFileInfo>>(
               future: _getFilelist(),
               builder: (context, snapshot) {
                 if (snapshot.hasData) {
                    return Text("Files Found");
                 }
                 else {
                    return Text("Still looking");
                 }
               } //end of builder
             ), //end of future builder
           ], //end of children
         ), //end of column
       ), //end of center
    ); //end of scaffold
  } 

下面是 localFileHelper.getFileList() 方法的代码:

  List<CardFileInfo> getFileList() {

    List<CardFileInfo> cardInfoList = [];
    final dirName = getApplicationDocumentsDirectory();

    // *** if I uncomment the following two lines, the process works *** 
    // cardInfoList.add(CardFileInfo("dummy.tsv"));
    // return cardInfoList;

    dirName.then((dir) { // <---------- problem seems occurs here with the future
      final files = dir.list().toList();
      files.then((values){
        values.forEach((element) {
          var type = element.path.toString().split(".").last.trim();
          if (type == "tsv") {
            var currCard = CardFileInfo(element.path.toString().trim());
            cardInfoList.add(currCard);
          }
        }); //end of foreEach
        return cardInfoList;
      }); //end of files.then
    }); //end of dirName.then
  } //end of getFileList()

当我单步执行代码时,“返回文本(”仍在寻找“);” 行最多执行两次。

该函数最终返回该值,但似乎 FutureBuilder 没有等待足够长的时间来返回该值。

我是 Flutter 和 Dart 的新手,这个问题真的让我很困惑。

标签: flutterdart

解决方案


您对问题发生位置的直觉是正确的;它发生在.then通话中。发生这种情况的原因是因为.then立即返回(它是“非阻塞的”),因此该方法将立即返回。Future 将在没有附加值的情况下完成,因为.then调用不会完成。在将来的某个时候,应该填充列表,但您将不知道何时使用当前方法。

我可以想到三种解决方案来解决这个问题:

  1. (我会推荐这种方法)使用async/await关键字使您的方法更容易异步。我不能保证这会按原样工作(自从我处理 Dart/Flutter 以来已经有几个月了),所以一些语法可能是错误的,但想法就在那里。
 Future<List<CardFileInfo>> getFileList() async {
    List<CardFileInfo> cardInfoList = [];
    final dirName = await getApplicationDocumentsDirectory();

    final files = await dirName.list().toList();
    for (final element in files) {
      final type = element.path.toString().split(".").last.trim();
      if (type == "tsv") {
        final currCard = CardFileInfo(element.path.toString().trim());
        cardInfoList.add(currCard);
      }
    }

    return cardInfoList;
  } //end of getFileList()
  1. 使用Completer. 这给了你更多的控制权,但在这种情况下我不推荐它,因为它需要样板文件并且会在这里有点损害可读性。
  2. initState在将填充列表的 a中调度调用StatefulWidget,然后setState在获取完成时使用调用来更新 UI。

推荐阅读