Home > front end >  Calling ListView inside ListView recursively
Calling ListView inside ListView recursively

Time:09-01

I'm trying to list all of my comments inside ListView. They have parent - children relationship and I wanna show them from method which calls itself recursively when pressed button to show child comments.

listViewComments(List<Comments>? comments) {
    return ListView.builder(
      scrollDirection: Axis.vertical,
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: comments!.length,
      itemBuilder: (BuildContext context, int index) {
        return Padding(
          padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 4),
          child: Card(
            child: ListTile(
              leading: CircleAvatar(
                backgroundImage: NetworkImage(
                    getPictureOfUser(comments[index].userId),
                    headers: tokenWithHeader),
              ),
              title: SizedBox(
                width: 300,
                child: Text(
                    "${comments[index].userFirstName} ${comments[index].userLastName}"),
              ),
              subtitle: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(comments[index].text),
                  Row(
                    children: [
                      TextButton(
                        onPressed: () {},
                        child: Wrap(
                            crossAxisAlignment: WrapCrossAlignment.center,
                            children: const [
                              Icon(Icons.reply),
                              Text(
                                'REPLY',
                                style: TextStyle(
                                  fontSize: 9.0,
                                ),
                              ),
                            ]),
                      ),
                      if (comments[index].childComments.isNotEmpty)
                        TextButton(
                          onPressed: () {
                            listViewComments(comments[index].childComments);
                          },
                          child: Text(           //show if there's child comment
                            'SHOW (${comments[index].childComments.length})',
                            style: const TextStyle(
                              fontSize: 9.0,
                            ),
                          ),
                        ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }

When I execute this code nothing happens. Why is that and is there any better way to do this?

CodePudding user response:

You'd need a state to show/hide the comments. To do it so, you can extract a StatefulWidget with this state or use Screenshot

  listViewComments(List<Comments>? comments) {
    return ListView.builder(
      scrollDirection: Axis.vertical,
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      itemCount: comments!.length,
      itemBuilder: (BuildContext context, int index) {
        return Padding(
          padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 4),
          child: Builder(builder: (context) {
            var showChildComments = false;
            return StatefulBuilder(builder: (context, setState) {
              return Card(
                child: ListTile(
                  leading: CircleAvatar(
                      backgroundImage: NetworkImage(
                          getPictureOfUser(comments[index].userId),
                          headers: tokenWithHeader),
                      ),
                  title: SizedBox(
                    width: 300,
                    child: Text(
                        "${comments[index].userFirstName} ${comments[index].userLastName}"),
                  ),
                  subtitle: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(comments[index].text),
                      Row(
                        children: [
                          TextButton(
                            onPressed: () {},
                            child: Wrap(
                                crossAxisAlignment: WrapCrossAlignment.center,
                                children: const [
                                  Icon(Icons.reply),
                                  Text(
                                    'REPLY',
                                    style: TextStyle(
                                      fontSize: 9.0,
                                    ),
                                  ),
                                ]),
                          ),
                          if (comments[index].childComments.isNotEmpty)
                            TextButton(
                              onPressed: () {
                                //listViewComments(comments[index].childComments);
                                setState(
                                  () => showChildComments = !showChildComments,
                                );
                              },
                              child: Text(
                                //show if there's child comment
                                '${showChildComments ? 'HIDE' : 'SHOW'} (${comments[index].childComments.length})',
                                style: const TextStyle(
                                  fontSize: 9.0,
                                ),
                              ),
                            ),
                        ],
                      ),
                      if (showChildComments)
                        listViewComments(comments[index].childComments),
                    ],
                  ),
                ),
              );
            });
          }),
        );
      },
    );
  • Related