Search code examples
flutterflutter-pageview

Flutter PageView check if page changed using drag gesture or animateToPage()


In a Scaffold page with something like the following structure

@override
Widget build(BuildContext context){
  body: PageView(
          controller: _controller;
          children: <Widget>[Page1(), Page2(), Page3()];
        );
  bottomNavigationBar: BottomNavBar(
                         onItemSelected: (index) => _controller.animateToPage()
                       )
}

there are two ways to go from Page2() to Page1():

  • Swipe the screen from left to right
  • Tap the Page1() icon on the bottomNavigationBar, and thus calling _controller.animateToPage(0)

The problem is, how can I tell if the page is changed through swiping gesture or animateToPage() function?

Thanks.


Solution

  • Maybe you can add a flag to set if animateToPage is ongoing or not.

    Sample:

    import 'package:flutter/material.dart';
    
    void main() => runApp(Root());
    
    class Root extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final PageController controller = PageController();
        bool isAnimateToPage = false;
    
        controller.addListener(() {
          print('LISTENER isAnimateToPage = $isAnimateToPage');
        });
    
        return MaterialApp(
          home: Scaffold(
            body: Column(
              children: <Widget>[
                Expanded(
                  child: PageView(
                    controller: controller,
                    onPageChanged: (int page) {
                      print(
                          'ONPAGECHANGED isAnimateToPage = $isAnimateToPage ; page = $page');
                    },
                    children: <Widget>[
                      const Center(child: Text('page 1')),
                      const Center(child: Text('page 2')),
                      const Center(child: Text('page 3')),
                    ],
                  ),
                ),
                FlatButton(
                  onPressed: () async {
                    isAnimateToPage = true;
                    await controller.animateToPage(
                      controller.page.toInt() + 1,
                      duration: const Duration(seconds: 1),
                      curve: Curves.easeIn,
                    );
                    isAnimateToPage = false;
                  },
                  child: const Text('Next'),
                ),
              ],
            ),
          ),
        );
      }
    }