Search code examples
flutteranimationnavigation

Animated page indicator on Flutter


I'm looking to create a navigator indicator for 2 pages working with a single bar that moves from left to right exactly like the following video :

https://youtu.be/LGmlxRQnXkE

Here is main code of the page :

Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              pageSelector("Upcoming", selectedPage==0, 0),
              pageSelector("Previous", selectedPage==1, 1)
            ],
          ),

          Expanded(
            child: PageView(
              controller: pageController,
              onPageChanged: (int page) {
                setState(() {
                  selectedPage=page;
                });
              },
              children: const [
                UpcomingPage(),
                PreviousPage()
              ],
            ),
          )

and here is the code of the pageSelector :

int selectedPage=0;
  PageController pageController=PageController();

  Widget pageSelector(String text, bool selected, int number){
    return Expanded(
      child: GestureDetector(
        onTap: (){
          pageController.animateToPage(number, duration: const Duration(milliseconds:300), curve: Curves.easeInOut);
          setState(() {
            selectedPage = number;
          });
        },
        child: Container(
          decoration: BoxDecoration(
            border: Border(
              bottom: selected ? BorderSide(color: Colpal.main, width: 2) : BorderSide(
                color: Colpal.grey,
                width: 0.1
              )
            )
          ),
          child: Padding(
            padding: const EdgeInsets.only(bottom: 8),
            child: Text(
              text,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 17,
                color: selected ? null : Colpal.grey,
                fontWeight: FontWeight.w500
              ),
            ),
          ),
        ),
      ),
    );
  }

Solution

  • The built-in TabBar widget handles this for you:

    return DefaultTabController(                   
      length: 3,                                   
      child: Scaffold(                             
        appBar: AppBar(                            
          title: const Text('test'),               
          actions: const [Icon(Icons.more_horiz)],
          bottom: const TabBar(                    
            tabs: [                                
              Tab(                                 
                text: 'test',                      
              ),                                   
              Tab(                                 
                text: 'test',                      
              ),                                   
              Tab(text: 'test'),                   
            ],                                     
          ),                                       
        ),                                         
        extendBodyBehindAppBar: true,              
        backgroundColor: Colors.red,               
      ),                                           
    );                                             
    

    Rather than use a PageView, you can use TabBarView and add your pages inside of it. See the official Widget-of-the-week video here:

    https://www.youtube.com/watch?v=POtoEH-5l40