Home > Mobile >  Flutter: I wants to show message to the user only if the user reaches end of the ListView
Flutter: I wants to show message to the user only if the user reaches end of the ListView

Time:10-10

Below is my code but it is showing the SnackBar frequently when I reach the bottom of ListView. It also shows the SnackBar on the pages also but I wants to show it only one time how to do that.

final snackBar = SnackBar(content: const Text('Yay! A SnackBar!'));

 Expanded(
                child: ListView.builder(
                  controller: _scrollController,
                  itemCount: docs.length,
                  itemBuilder: (context, index) {
                    final doc = docs[index];
                    print(doc);
                    //_checkController();
                    _scrollController.addListener(() {
                      if (_scrollController.position.pixels ==
                          _scrollController.position.maxScrollExtent) {
                        ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      } else {
                        if (_scrollController.position.pixels !=
                            _scrollController.position.maxScrollExtent) {
                          return null;
                        }
                      }
                    });
                    return builddoc(doc);
                  },

CodePudding user response:

Because you are assigning new listeners every time item builder calls.

put this code in ititState so it just called once.

                  _scrollController.addListener(() {
                      if (_scrollController.position.pixels ==
                          _scrollController.position.maxScrollExtent) {
                        ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      } else {
                        if (_scrollController.position.pixels !=
                            _scrollController.position.maxScrollExtent) {
                          return null;
                        }
                      }
                    });

CodePudding user response:

Remove the listener from the itembuilder, instead use it in initState(),as everytime item is builded on listview, it will call this listener, so it is going on everytime item get builded.

CodePudding user response:

You can use Listener on ScrollController, your issue is that you assign Listener to controller in build method which is wrong, you should do it once in initState. This is a full example of what you want:

class ScrollPageTest extends StatefulWidget {
  const ScrollPageTest({Key? key}) : super(key: key);

  @override
  State<ScrollPageTest> createState() => _ScrollPageTest();
}

class _ScrollPageTest extends State<ScrollPageTest> {
  ScrollController controller = ScrollController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller.addListener(() {
      if (controller.position.atEdge) {
        if (controller.position.pixels != 0) {
          final snackBar = SnackBar(content: const Text('Yay! A SnackBar!'));
          ScaffoldMessenger.of(context).showSnackBar(snackBar);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        controller: controller,
        itemBuilder: (context, index) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: Text('data = $index'),
          );
        },
        itemCount: 100,
      ),
    );
  }
}

CodePudding user response:

Try this:

 bool isSnackBarShown = false;

 ...



    Expanded(
                child: ListView.builder(
                  controller: _scrollController,
                  itemCount: docs.length,
                  itemBuilder: (context, index) {
                    final doc = docs[index];
                    print(doc);
                    //_checkController();
                    _scrollController.addListener(() {
                      if ((_scrollController.position.pixels ==
                          _scrollController.position.maxScrollExtent)
                      && !isSnackBarShown) {
                      isSnackBarShown = true;
ScaffoldMessenger.of(context).showSnackBar(snackBar);
                          } else {
                            if (_scrollController.position.pixels !=
                                _scrollController.position.maxScrollExtent) {
                              return null;
                            }
                          }
                        });
                        return builddoc(doc);
                      },
  • Related