Scroll Controller synchronized with Tabs in flutter

Viewed 1725

I have a scrollcontroller which manages the scroll functionality of my gridview, but above the gridview I have a tabbar, which, when each tab is pressed, scrolls the page to different positions in the gridview. As shown in the code below. But when I scroll through the gridview itself, the tabs don't change their selection. I need to know how to achieve this, similar to this:

https://www.youtube.com/watch?v=LrOR5QOCHBI

    Future<void> _scrollControllerAnimation(double offset) {
      return _scrollController.animateTo(
        offset,
        duration: Duration(milliseconds: 500),
        curve: Curves.easeIn,
      );
    }

TabBar(
                  controller: _tabController,
                  isScrollable: true,
                  labelColor: Colors.black,
                  unselectedLabelColor: Colors.black.withOpacity(0.3),

                  onTap: (int){

                    switch (int) {

                      case 0: _scrollControllerAnimation(0);break;
                      case 1: _scrollControllerAnimation(70);break;
                      case 2: _scrollControllerAnimation(140);break;
                      case 3: _scrollControllerAnimation(210);break;
                      case 4: _scrollControllerAnimation(280);break;
                      case 5: _scrollControllerAnimation(350);break;
                      case 6: _scrollControllerAnimation(420);break;
                      case 7: _scrollControllerAnimation(490);break;
                      case 8: _scrollControllerAnimation(560);break;
                      case 9: _scrollControllerAnimation(630);break;
                      case 10: _scrollControllerAnimation(700);break;
                      case 11: _scrollControllerAnimation(770);break;

                      default: _scrollControllerAnimation(0);
                    }
                  },

                  tabs: choices.map((Choice choice) {
                      return Tab(
                      text: choice.title,
                    );
                  }).toList(),
                ),

1 Answers

You can do this by adding a listener to the scroll controller and in the listener, depending on the scroll controller's offset, you can call animateTo on your tabController. You can instantiate the controllers and attach the listener in initState, as it only is called once during the widget's lifecycle.

That might look something like this:

@override
void initState() {
  _scrollController = ScrollController();
  _tabController = TabController(vsync: this, length: 8);

  _scrollController.addListener(() {
    int tabIndex = _tabController.index;
    int targetIndex = _targetIndex(_scrollController.offset);
    if (targetIndex != tabIndex) {
      _tabController.animateTo(
        targetIndex,
        duration: Duration(milliseconds: 400),
      );
    }
  });
  super.initState();
}
Related