在 Flutter 中,如何确保用于构建 GridView 的数据可用?

In Flutter, How can I make sure that the data used to build a GridView is available?

我有一组文件存储在应用程序目录中。每个都包含要在 GridView 小部件中显示的 Uint8List 数据。由于 Dart 的异步特性,我如何才能确保在 Widget 构建开始之前能够获得可用的文件数和文件名。由于files/names的数字是动态的,所以我不得不扫描App目录。以下是部分代码片段。我把获取文件名和生成Uint8List数据集的功能放在了initState中,但有时不能正常使用。感谢对此问题的任何反馈。

class _PageAState extends State<PageA> {

    List<String> fileNames=[];
    List<Uint8List> uIntData
    int numFiles=0;
    
    /*get file names (starting with "XYZ", stored in App directory*/
    
    _getFileName() async {
    fileNames = [];
    
    String keyWord = "XYZ";
    
    List files = new List();
 //   var lock = new Lock();   // try https://pub.dev/packages/synchronized package with no luck
   // await lock.synchronized(() async {
      String directory = (await getApplicationDocumentsDirectory()).path;
      files = Directory("$directory").listSync();
      for (FileSystemEntity f in files) {
        if (f.path.contains(keyWord)) {
          fileNames.add(f.path);
          print(f.path);
        }
      }
    // });
  }

  /*get a set of Uint8List data */
  
  _getImageData() async {
    await _getFileName();
    numFiles = fileNames.length;
   
    for (int i = 0; i < numFiles; i++) {
      Uint8List dData =
          (await rootBundle.load(fileNames[i])).buffer.asUint8List();
      uIntData.add(dData);
    }
  }


 @override
  initState() {
    super.initState();
    /** load Uint8List data set async ***/
    _getImageData();
}   

 Widget buildGridView(BuildContext context) {
    var orientation = Orientation.portrait;
    return (GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3),
    // how to make sure that numFiles is properly set ???     
      itemCount: numFiles,
      itemBuilder: (BuildContext ctx, int index) {
        return Padding(
          padding: EdgeInsets.all(20),
          child: Stack(children: <Widget>[
            GestureDetector(
              child: Card(
                shape: Border.all(
                  width: 5,
                ),
                elevation: 20,
                color: Colors.greenAccent,
                child: SizedBox(
                  child: (uIntData.isEmpty || uIntData[index] == null)
                      ? CircularProgressIndicator()
                      : Image.memory(uIntData[index]),
                  width: 120,
                  height: 120,
                ),
              ),
              onTap: () {
              },
              onLongPress: () {
              },
            ),
          ]),
        );
      },
    ));
  }
  
    
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: buildGridView(context),
    );
  } 
}

您必须初始化 uIntDataitemCount 使用您的 uIntData 列表的长度,例如:

声明:

  List<Uint8List> uIntData = [];

计算实物:

  itemCount: uIntData.length,

此外,您可以仅用一种方法重构 _getFileName_getImageData,因为当您只能使用一种方法时,您使用 2 作为 bucle .

检索所有文件后再次尝试刷新 UI:

  @override
  initState() {
    super.initState();
    /** load Uint8List data set async ***/
    _getImageData().then((){
setState(() {});
});
}