Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

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

I have a set of files stored in App directory. Each one contains Uint8List data to be displayed in a GridView Widget. Because of the async nature of Dart, how can I make sure that I can get the number of files and the file names available before the Widget build starts. Since the number of files/names is dynamic, I have to scan the App directory. The following is the partial code snippet. I put the functions of getting file names and generating Uint8List data set in initState but sometimes it doesn’t work properly. Appreciate any feedback on this question.

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),
    );
  } 
}
question from:https://stackoverflow.com/questions/65929991/in-flutter-how-can-i-make-sure-that-the-data-used-to-build-a-gridview-is-availa

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try to refresh the UI once more after all files are retrieved:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...