Search code examples
flutternavigationnavigator

Can't use WIllPopScope in PageView children


I have a Page inside a Pageview, 4 pages to be exact. The first page is the Home Page and I want the other 3 will go back to the Home Page if I press the Back Button, but it seems that WillPopScope doesn't work in the PageView Children. When I press the back button it always goes back to the Page before the HomePage.

Is it possible to use WillPopScope inside PageView children, or is that any other approach for what I want?

Here is what my Home page that have PageView code like :

 Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            backgroundColor: Theme.of(context).primaryColor,
            selectedItemColor: Colors.white,
            unselectedItemColor: Colors.grey[400],
            currentIndex: currentIndex,
            onTap: (int newIndex) {
              setState(() {

                // Ada animasi slide
                _pageController.animateToPage(
                  newIndex,
                  duration: const Duration(
                    milliseconds: 200,
                  ),
                  curve: Curves.ease,
                );
              });
            },
            items: const [
              BottomNavigationBarItem(
                label: 'Home',
                icon: Icon(Icons.home),
              ),
              BottomNavigationBarItem(
                label: 'Prayers',
                icon: ImageIcon(AssetImage('assets/icons/union.png')),
              ),
              BottomNavigationBarItem(
                label: 'Attendance',
                icon: ImageIcon(AssetImage('assets/icons/inscription.png')),
              ),
              BottomNavigationBarItem(
                label: 'Setting',
                icon: Icon(Icons.settings),
              ),
            ],
          ),
          body: SizedBox.expand(
            child: PageView(
              controller: _pageController,
              onPageChanged: (index) {
                setState(() {
                  currentIndex = index;
                });
              },
              physics: const NeverScrollableScrollPhysics(),
              children: [
                const MainMenuPage(),
                PrayersPage(controller: _pageController,),
                Container(
                  color: Colors.indigo,
                ),
                Container(
                  color: Colors.teal,
                ),
              ],
            ),
          )),

I want to be able to go back to the MainMenuPage() when I press the back button inside the other 3 pages,


Solution

  • The Problem:

    The WillPopScope is just responsible for the interactions with the Navigation module. In your case, you haven't pushed any route page to the navigator, therefore there is nothing to pop!. Even if your app contains different route pages, using this method will returns you back to the previous page without which probably doesn't have any PageView!

    Correct way:

    For navigating between PageView pages you need to use the related controller it provides. This is an example code for reference.

    class PageViewExample extends StatefulWidget {
      @override
      _PageViewExampleState createState() => _PageViewExampleState();
    }
    
    class _PageViewExampleState extends State<PageViewExample> {
      final PageController _pageController = PageController();
      int _currentPage = 0;
    
      @override
      void dispose() {
        _pageController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('PageView Example'),
          ),
          body: PageView(
            controller: _pageController,
            onPageChanged: (int page) {
              setState(() {
                _currentPage = page;
              });
            },
            children: <Widget>[
              Container(
                color: Colors.blue,
                child: Center(
                  child: Text(
                    'Page 1',
                    style: TextStyle(fontSize: 24, color: Colors.white),
                  ),
                ),
              ),
              Container(
                color: Colors.green,
                child: Center(
                  child: Text(
                    'Page 2',
                    style: TextStyle(fontSize: 24, color: Colors.white),
                  ),
                ),
              ),
              Container(
                color: Colors.orange,
                child: Center(
                  child: Text(
                    'Page 3',
                    style: TextStyle(fontSize: 24, color: Colors.white),
                  ),
                ),
              ),
            ],
          ),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _currentPage,
            onTap: (int page) {
              _pageController.animateToPage(
                page,
                duration: Duration(milliseconds: 500),
                curve: Curves.ease,
              );
            },
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Page 1',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.business),
                label: 'Page 2',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.school),
                label: 'Page 3',
              ),
            ],
          ),
        );
      }
    }