Moataz Harrabi
Moataz Harrabi

Reputation: 11

How to manage state on showGeneralDialog so I can update ListView when scrolling

I have this function that shows a general dialog that contains a ListView of cards which have a scroll controller so that I can load more data on scroll, the problem is that I can't find a way to setState without a widget that have an onChange method, how can I manage the state of the StatefulBuilder when scrolling ?

void showReviewDialog(BuildContext context) {
    final scrollController = ScrollController();
    scrollController.addListener(() {
      if (scrollController.position.pixels ==
          scrollController.position.maxScrollExtent) {
        StoreDetailsController.find.getStoreReviews();
      }
    });
    showGeneralDialog(
        barrierDismissible: true,
        barrierLabel: MaterialLocalizations
            .of(context)
            .modalBarrierDismissLabel,
        context: context,
        pageBuilder: (BuildContext context, Animation animation,
            Animation secondaryAnimation) {
          return StatefulBuilder(
            builder: (context, setStateDialog) {
              return Center(
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.grey.shade200,
                      borderRadius:
                      const BorderRadius.all(Radius.circular(20))),
                  margin: const EdgeInsets.fromLTRB(30, 50, 30, 50),
                  padding: const EdgeInsets.all(10),
                  child: Column(
                    children: [
                      Text(
                        StoreDetailsController.find.store!.businessName,
                        overflow: TextOverflow.ellipsis,
                        style: Theme
                            .of(context)
                            .textTheme
                            .displayMedium,
                      ),
                      Expanded(
                        child: ListView(
                          controller: scrollController,
                          physics: const ScrollPhysics(),
                          shrinkWrap: true,
                          children: List.generate(
                            StoreDetailsController.find.storeRatings.length,
                                (index) {
                              return ReviewCard(
                                  rating: StoreDetailsController.find
                                      .storeRatings[index]);

                            },
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              );
            },
          );
        });
  }

Upvotes: 0

Views: 117

Answers (1)

Moataz Harrabi
Moataz Harrabi

Reputation: 11

the problem was that the scroll controller listener was outside of the stateful builder, all I had to do is moving it inside and now everything is working fine, here is the correct code

void showReviewDialog(BuildContext context, ) {
    final scrollController = ScrollController();
    showGeneralDialog(
        barrierDismissible: true,
        barrierLabel:
            MaterialLocalizations.of(context).modalBarrierDismissLabel,
        context: context,
        pageBuilder: (BuildContext context, Animation animation,
            Animation secondaryAnimation) {
          return StatefulBuilder(
            builder: (context, setStateDialog) {
              //Moved here
              scrollController.addListener(() {
                if (scrollController.position.pixels ==
                    scrollController.position.maxScrollExtent) {
                  StoreDetailsController.find.getStoreReviews();
                  setStateDialog(() {

                  },);
                }
              });
              return Center(
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.grey.shade200,
                      borderRadius:
                          const BorderRadius.all(Radius.circular(20))),
                  margin: const EdgeInsets.fromLTRB(30, 50, 30, 50),
                  padding: const EdgeInsets.all(10),
                  child: Column(
                    children: [
                      Text(
                        StoreDetailsController.find.store!.businessName,
                        overflow: TextOverflow.ellipsis,
                        style: Theme.of(context).textTheme.displayMedium,
                      ),
                      Expanded(
                        child: ListView(
                          controller: scrollController,
                          physics: const ScrollPhysics(),
                          shrinkWrap: true,
                          children: List.generate(
                            StoreDetailsController.find.storeRatings.length,
                            (index) {
                              return ReviewCard(
                                  rating: StoreDetailsController
                                      .find.storeRatings[index]);
                            },
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              );
            },
          );
        });
  }

Upvotes: 0

Related Questions