flutterflutter-pageview

TabPageSelector weird behaviour


I am trying to play with this piece of code provided here

Now, at the end of the code there are 2 IconButton, it's thanks to them that we can move from one page to the next one (there are 3 pages in total) and it works like this:

But I don't like it that way very much and I want it to work this way:

Willing to change this I modified the code of the 2 IconButton inside the function OnPressed to this:

    //first IconButton
    onPressed: () {
              if (currentPageIndex == 0) {
                 onUpdateCurrentPageIndex(2);
              } else {
                 onUpdateCurrentPageIndex(currentPageIndex - 1);
              }
            },

and this:

    //second IconButton
    onPressed: () {
              if (currentPageIndex == 2) {
                onUpdateCurrentPageIndex(0);
              } else {
                onUpdateCurrentPageIndex(currentPageIndex + 1);
              }
            },

And now it works like I wanted to but there is a problem with the TabPageSelector, the 3 dots between the 2 arrows.

You can try it yourself clicking on the link that I provided and modifying the code with the one I wrote.

A very random behaviour and I don't understand why, can someone explain to me why this is happening? and how I can fix it ofc. Thanks in advance!


Solution

  • The problem is at the _updateCurrentPageIndex() method.

    Inside the method there is a .animateToPage call which returning a Future<void> (refs).

    void _updateCurrentPageIndex(int index) {
      _tabController.index = index;
      _pageViewController.animateToPage( // <- return the Future<void>
        index,
        duration: const Duration(milliseconds: 400),
        curve: Curves.easeInOut,
      );
    }
    

    So why your dot indicator moving weird like this

    issue demo

    Is because you change the indicator position and page view position at a same time, but the animateToPage() have to wait a little time to complete, so when the dot is moved to the target position, it will moved again to middle because the pageview position is still in the center at the moment.

    The solution is simple:

    void _updateCurrentPageIndex(int index) async { // <- add async
      await _pageViewController.animateToPage( // <- move this up and add await
        index,
        duration: const Duration(milliseconds: 400),
        curve: Curves.easeInOut,
      );
      _tabController.index = index; // <- move this below the animateToPage
    }
    
    1. Add the async keywod to the mothod
    2. Move the assignment of _tabController below the animateToPage call
    3. Add await keyword to animateToPage

    Now, the dot indicator will move after the animateToPage is done.

    result demo

    Hopefully it can solve your problem, Thanks 😉