繁体   English   中英

如何在列表视图构建器上应用异步操作?

[英]How to apply an async operation on list view builder?

我试图从Firebase获取一组加密的数据文档,并在flutter的列表视图中显示它们。

我使用流构建器来获取数据,并开始在列表视图中显示它。 但是我无法对每个数据项执行解密操作,因为它是异步操作。 做这个的最好方式是什么?

StreamBuilder<QuerySnapshot>(
              stream: Firestore.instance
                  .collection(ScopedModel.of<User>(context).userId)
                  .snapshots(),
              builder: (BuildContext context,
                  AsyncSnapshot<QuerySnapshot> snapshot) {
                if (snapshot.hasError)
                  return new Text('Error: ${snapshot.error}');

                switch (snapshot.connectionState) {
                  case ConnectionState.waiting:
                    return Center(
                        child: new Container(
                      child: CircularProgressIndicator(),
                    ));
                  default:
                    if (snapshot.data.documents.length == 0) {
                      return Container(
                        padding: EdgeInsets.all(16.0),
                        child: Row(
                          children: <Widget>[
                            Text('Empty',),
                          ],
                        ),
                      );
                    }

                    final docs = snapshot.data.documents;

                    return ScrollConfiguration(
                      behavior: ScrollBehavior(),
                      child: ListView.builder(
                        itemCount: len,
                        scrollDirection: Axis.horizontal,
                        itemBuilder: (context, position) {

                                  // Where should I decrypt the below data?
                                  // let decrypted = await myDecryptionFunction(docs[position]['myDataKey']) ;
                                  // the above is not working

                                  // this will show the encrypted text
                                  return Text(docs[position]['myDataKey']);
                        }




      ....

根据您的情况,可以将StreamController与帮助器类一起使用来保存信息。
以下仅是示例,但可以根据自己的需要进行调整。

// Helper classes
// adapt it to your own business case
class Notes {
  String title;
  String description;

  Notes({this.title, this.description});
}

class NotesFromDb {
  String connectionState;
  bool hasError;
  String error;
  List<Notes> notes;
  NotesFromDb({this.connectionState, this.hasError, this.error, this.notes});
}

// The Streambuilder
StreamBuilder<NotesFromDb>(
  stream: sController.stream,
  builder: (BuildContext context, AsyncSnapshot<NotesFromDb> snapshot) {
    // Here you can check for errors
    if (snapshot.data.hasError == true) {
      return Container(
        color: Colors.red,
        child: Text(snapshot.data.error),
      );
    }
    // Here you can check for your connection state
    if (snapshot.data.connectionState == 'Loading') {
      return Container(
        color: Colors.yellow,
        child: CircularProgressIndicator(),
      );
    }

    // Here you can show your data
    var info = snapshot.data.notes.map((doc) {
      return Text(doc.title);
    });

    return Center(
        child: Container(
      color: Colors.deepOrange,
      child: Column(
        children: info.toList(),
      ),
    ));
  })

// Here is how you can handle the decrypt data
// using a FloatingActionButton for loading the data (for example)
FloatingActionButton(
  onPressed: () async { // you would need to add the async

    List<Notes> theNotes; //just to hold the information
    // Use this to allow to show the CircularProgressIndicator
    sController.sink.add(NotesFromDb(connectionState: 'Loading'));

    var snapshots = Firestore.instance.collection('notes').snapshots();
    snapshots.listen((QuerySnapshot data) {
      theNotes = data.documents.map((DocumentSnapshot doc) {
        // Build your data
        return Notes(
            title: doc.data['title'],
            description: doc.data['description']);
      }).toList();
    }, onError: (err, stack) {
      // If an error happend then send the error to the stream
      sController.sink
          .add(NotesFromDb(hasError: true, error: err.error));
    });

    // Here you can to decrypt the documents with your function
    var decryptDocuments = await Future.delayed(Duration(seconds: 2)); //Whatever future function

    // Once you have the decrypt documents, you would need to send that to the stream.
    // set the connectionState to Done, so the spinner is not showed anymore.
    sController.sink.add(NotesFromDb(
        hasError: false, connectionState: 'Done', notes: decryptDocuments));
  },
  child: Icon(Icons.arrow_forward),
)

以该示例为例说明如何执行此操作。
希望对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM