首页 > 解决方案 > 在 Flutter 中,如何确保用于构建 GridView 的数据可用?

问题描述

我有一组文件存储在 App 目录中。每一个都包含要在 GridView Widget 中显示的 Uint8List 数据。由于 Dart 的异步特性,我如何确保在 Widget 构建开始之前可以获取文件的数量和可用的文件名。由于文件/名称的数量是动态的,我必须扫描 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),
    );
  } 
}

标签: flutterlistviewdartasynchronousgridview

解决方案


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

宣言:

  List<Uint8List> uIntData = [];

计算实物:

  itemCount: uIntData.length,

另外,您可以仅在一种方法中重构_getFileName_getImageData,因为当您只能使用一种时,您将 2 用于 bucle。


推荐阅读