flutterdartflutter-layoutflutter-pageviewflutter-dialog

onPageChanged with Future Dialog Flutter


I am trying to get my Flutter Dialog to show page indicator dots based off the onPageChanged setState and it doesnt seem to be working. What is happening is the dots are appearing and one is highlighted but as I swipe the dots are not following the current page. Any ideas? When I add a print statement to my setState I can see the activePage is corresponding with the current index. I am at odds as to why this is not working?

Future openDialog() => showDialog(
  context: context,
  builder: (BuildContext context) => Dialog(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.0),
        ),
        backgroundColor: const Color(0xFF64748b),
        child: Container(
          height: 300.0, // Change as per your requirement
          width: 300.0, // Change as per your requirement
          child: Column(
            children: [
              SizedBox(
                width: MediaQuery.of(context).size.width,
                height: 200,
                child: PageView.builder(
                  scrollDirection: Axis.horizontal,
                  pageSnapping: true,
                  itemCount: eqs.length,
                  controller: _pageController,
                  onPageChanged: (page)  {
                    setState(() {
                      activePage = page;
                      // print(activePage);
                    });
                  },
                  itemBuilder: (context, index) {
                    final titles = eqs[index];

                    return Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Container(
                          padding: const EdgeInsets.all(15.0),
                          child: Text(
                            titles.eqTitle,
                            style: const TextStyle(
                                color: Colors.white,
                                fontSize: 17,
                                fontWeight: FontWeight.bold),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(15.0),
                          child: Math.tex(
                            titles.eq,
                            mathStyle: MathStyle.display,
                            textStyle: const TextStyle(
                              color: Colors.white,
                              fontSize: 17,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ],
                    );
                  },
                ),
              ),
              Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: indicators(eqs.length, activePage))
            ],
          ),
        ),
      ));
    List<Widget> indicators(eqsLength, currentIndex) {
     return List<Widget>.generate(eqsLength, (index) {
       return Container(
         margin: const EdgeInsets.all(5.0),
         width: 10,
         height: 10,
         decoration: BoxDecoration(
         color: currentIndex == index ? Colors.greenAccent : Colors.black26,
         shape: BoxShape.circle),
          );
        });
       }

Solution

  • Hey if you're trying to have a page indicator at the bottom of your page view, you can just use a very simple package called smooth_page_indicator

    Future openDialog() => showDialog(
          context: context,
          builder: (BuildContext context) => Dialog(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(20.0),
            ),
            backgroundColor: const Color(0xFF64748b),
            child: Container(
              height: 300.0, // Change as per your requirement
              width: 300.0, // Change as per your requirement
              child: Column(
                children: [
                  SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height: 200,
                    child: PageView.builder(
                      scrollDirection: Axis.horizontal,
                      pageSnapping: true,
                      itemCount: eqs.length,
                      controller: _pageController,
                      itemBuilder: (context, index) {
                        final titles = eqs[index];
    
                        return Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Container(
                              padding: const EdgeInsets.all(15.0),
                              child: Text(
                                titles.eqTitle,
                                style: const TextStyle(
                                    color: Colors.white,
                                    fontSize: 17,
                                    fontWeight: FontWeight.bold),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: Math.tex(
                                titles.eq,
                                mathStyle: MathStyle.display,
                                textStyle: const TextStyle(
                                  color: Colors.white,
                                  fontSize: 17,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ],
                        );
                      },
                    ),
                  ),
                  // Add this
                  SmoothPageIndicator(
                      controller: _pageController, // PageController
                      count: eqs.length,
                      effect: WormEffect(), // your preferred effect
                      onDotClicked: (index) {})
                ],
              ),
            ),
          ),
        );
    
     
    

    But if you want to have your custom widget for the indicator, instead of updating the active page, update your current index.

    Hope you find this helpful!

    [AMIR SMILEY]