flutter dynamic expansionTile

前端 未结 3 2024
南方客
南方客 2020-12-16 06:10

Looking for some guidance on building expansionTile list dynamically. I have a successful Listview built dynamically from json API, but can not find any examples on buildin

3条回答
  •  一向
    一向 (楼主)
    2020-12-16 06:33

    Following Rainer Wittmann approach, I modified it to fit my needs and implemented for Cloud Firestore, but instead of futures I used streams.

    My basic structure of Cloud Firestore is:

    Collection projects

    • name

    • Collection surveys:

      • surveyName

    Solution:

    class ProjectList extends StatelessWidget {
      ProjectList({this.firestore});
    
      final Firestore firestore;
    
      @override
      Widget build(BuildContext context) {
        return StreamBuilder(
          stream: firestore.collection('projects').snapshots(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (!snapshot.hasData) return const Text('Loading...');
            //final int projectsCount = snapshot.data.documents.length;
            List documents = snapshot.data.documents;
            return ExpansionTileList(
              firestore: firestore,
              documents: documents,
            );
          },
        );
      }
    }
    
    class ExpansionTileList extends StatelessWidget {
      final List documents;
      final Firestore firestore;
    
      ExpansionTileList({this.documents, this.firestore});
    
      List _getChildren() {
        List children = [];
        documents.forEach((doc) {
          children.add(
            ProjectsExpansionTile(
              name: doc['name'],
              projectKey: doc.documentID,
              firestore: firestore,
            ),
          );
        });
        return children;
      }
    
      @override
      Widget build(BuildContext context) {
        return ListView(
          children: _getChildren(),
        );
      }
    }
    
    class ProjectsExpansionTile extends StatelessWidget {
      ProjectsExpansionTile({this.projectKey, this.name, this.firestore});
    
      final String projectKey;
      final String name;
      final Firestore firestore;
    
      @override
      Widget build(BuildContext context) {
        PageStorageKey _projectKey = PageStorageKey('$projectKey');
    
        return ExpansionTile(
          key: _projectKey,
          title: Text(
            name,
            style: TextStyle(fontSize: 28.0),
          ),
          children: [
            StreamBuilder(
                stream: firestore
                    .collection('projects')
                    .document(projectKey)
                    .collection('surveys')
    
                    .snapshots(),
                builder:
                    (BuildContext context, AsyncSnapshot snapshot) {
                  if (!snapshot.hasData) return const Text('Loading...');
                  //final int surveysCount = snapshot.data.documents.length;
                  List documents = snapshot.data.documents;
    
                  List surveysList = [];
                  documents.forEach((doc) {
                    PageStorageKey _surveyKey =
                        new PageStorageKey('${doc.documentID}');
    
                    surveysList.add(ListTile(
                      key: _surveyKey,
                      title: Text(doc['surveyName']),
                    ));
                  });
                  return Column(children: surveysList);
                })
          ],
        );
      }
    }
    

    Hope this helps to those lost in nested collections in cloud firestore.

    Happy coding!

提交回复
热议问题