3

I have a custom BottomAppBar with PageView for pages. I am trying to change the pages as the user clicks on items in the BottomAppBar. I am using Provider to manage Global State. Clicking on items triggers the value change in the provider but there is no method in PageView to trigger page change on a value change. How can I achieve this? Below is my code.

My Provider:

class CurrentPage extends ChangeNotifier {
  int _currentPage = 0;
  int get currentPage => _currentPage;

  setCurrentPage(int val) {
    _currentPage = val;
    notifyListeners();
  }
}

A BottomAppBar Item:

 InkWell(
                onTap: () {
                  context.read<CurrentPage>().setCurrentPage(0);
                },
                child: Padding(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 26.5, vertical: 17.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Icon(
                        CustomIcons.home,
                        size: 18.0,
                        color: context.watch<CurrentPage>().currentPage == 0
                            ? Color(0xFF2C1DEB)
                            : Color(0xFFCCCCD5),
                      ),
                      SizedBox(height: 9.0),
                      Text(
                        'HOME',
                        style: TextStyle(
                          color: context.watch<CurrentPage>().currentPage == 0
                              ? Color(0xFF2C1DEB)
                              : Color(0xFFCCCCD5),
                          fontWeight: FontWeight.w800,
                          fontSize: 10.0,
                          letterSpacing: 1.0,
                        ),
                      ),
                    ],
                  ),
                ),
              ),

PageView:

class Pages extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final PageController _pageController =
        PageController(initialPage: context.watch<CurrentPage>().currentPage);

    return PageView(
      onPageChanged: (int) {},
      controller: _pageController,
      scrollDirection: Axis.horizontal,
      pageSnapping: true,
      children: [
        Container(
          color: Colors.green,
          child: Text('Home Page'),
        ),
        Container(
          child: Text('Profile Page'),
        ),
        Container(
          child: Text('Search Page'),
        ),
        Container(
          child: Text('Jobs Page'),
        ),
      ],
    );
  }
}
Saad Momin
  • 97
  • 1
  • 6

2 Answers2

6

This is how you can make it. Once you call notifyListener from your provider, if the currentPage has changed, this will go to the new selected page

class Pages extends StatelessWidget {
      final PageController _pageController =
            PageController(initialPage:0);
      @override
      Widget build(BuildContext context) {


    return Consumer<CurrentPage>(builder:(ctx, currentPage,  widget){

     final pageView = PageView(
          onPageChanged: (int) {},
          controller: _pageController,
          scrollDirection: Axis.horizontal,
          pageSnapping: true,
          children: [
            Container(
              color: Colors.green,
              child: Text('Home Page'),
            ),
            Container(
              child: Text('Profile Page'),
            ),
            Container(
              child: Text('Search Page'),
            ),
            Container(
              child: Text('Jobs Page'),
            ),
          ],);
          if(currentPage.currentPage != _pageController.page.floor()){
            _pageController.jumpToPage(currentPage.currentPage);
          }
          return pageView;
          }
        );
      }
    }
Constantin N.
  • 2,739
  • 2
  • 16
  • 27
  • Thanks buddy. But cant access PageController.page before the pageview is built. Getting below error: PageController.page cannot be accessed before a PageView is built with it. – Saad Momin May 21 '20 at 14:44
  • Hello Saad. I've updated my answer. please take a look – Constantin N. May 22 '20 at 21:23
  • That does it. Thanks a ton buddy – Saad Momin May 23 '20 at 21:35
  • I need help in a similar situation.. Can someone please take a look at this? Thanks in advance... https://stackoverflow.com/questions/67923192/provider-state-management-for-pagecontroller-in-flutter – user10033434 Jun 12 '21 at 09:51
0

You should use animateToPage or jumpToPage methods in PageViewController. also you need to make your Page widget StatefullWidget.

Payam Zahedi
  • 827
  • 7
  • 20