How to scroll to next tab using TabBarView into TabBarView

111

This logic can be simplified using PageView, same approach can apply on other widgets like IndexedStack.

Full snippet on dartPad.

class MyMainTabVarView extends StatefulWidget {
  const MyMainTabVarView({Key? key}) : super(key: key);

  @override
  _MyMainTabVarViewState createState() => _MyMainTabVarViewState();
}

class _MyMainTabVarViewState extends State<MyMainTabVarView>
    with TickerProviderStateMixin {
  late final TabController controllerForMainTabVarView =
      TabController(length: 3, vsync: this, initialIndex: 0);
  late final TabController topTabBarController =
      TabController(length: 2, vsync: this, initialIndex: 0);

  late PageController pageController = PageController();

  onPageChange(int index) {
    debugPrint("page num $index");
    controllerForMainTabVarView.animateTo(
      index ~/ 2,
      duration: const Duration(milliseconds: 400),
      curve: Curves.ease,
    );
    topTabBarController.animateTo(
      index % 2,
      duration: const Duration(milliseconds: 400),
      curve: Curves.ease,
    );

    setState(() {});
  }

  void navigation(bool isTopController) {
    //skip 1st build
    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
      int mainTabBarIndex = controllerForMainTabVarView.index;
      int topTabBarIndex = topTabBarController.index;

      /// switch to TopTabBar index=0
      if (!isTopController) {
        topTabBarIndex = 0;
        topTabBarController.index = 0;
      }
      debugPrint("main $mainTabBarIndex top $topTabBarIndex");

      pageController.animateToPage(
        topTabBarIndex + mainTabBarIndex * 2,
        duration: const Duration(milliseconds: 400),
        curve: Curves.ease,
      );
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Column(
        children: [
          TabBar(
              controller: topTabBarController,
              tabs: const [
                Tab(text: "Page1"),
                Tab(text: "Page2"),
              ],
              onTap: (_) {
                navigation(true);
              }),
          Expanded(
            child: Container(
              color: Theme.of(context).scaffoldBackgroundColor,
              child: PageView(
                controller: pageController,
                onPageChanged: onPageChange,
                children: const [
                  Center(child: Text(' MyStful1 Page1')),
                  Center(child: Text(' MyStful1 Page2')),
                  Center(child: Text(' MyStful2 Page1')),
                  Center(child: Text(' MyStful2 Page2')),
                  Center(child: Text(' MyStful3 Page1')),
                  Center(child: Text(' MyStful3 Page2')),
                ],
              ),
            ),
          ),
          TabBar(
            // here i am use TabBar at the bottom of the screen instead of bottom Navigation Bar
            controller: controllerForMainTabVarView,
            onTap: (_) {
              navigation(false);
            },
            tabs: const [
              Tab(
                text: "My Stful 1",
              ),
              Tab(
                text: "My Stful 2",
              ),
              Tab(
                text: "My Stful 3",
              ),
            ],
          )
        ],
      ),
    );
  }
}
Share:
111
Mohammed Hamdan
Author by

Mohammed Hamdan

Updated on January 03, 2023

Comments

  • Mohammed Hamdan
    Mohammed Hamdan over 1 year

    I have TabBarView into TabBarView like following

    //stful
    late final TabController _controller1 = TabController( length: 3, vsync: this,initialIndex: 0);
     bottom:  TabBar(
      controller: _controller1,
    
     tabs: const [
     Tab(text: "Stful1",),
    Tab(text: "Stfu2",),
    Tab(text: "Stfu3",),
    
     ],
    ),
    
        TabBarView(
        controller: _controller1
        children: [
        Stful1()
        Stful2()
        Stful3()
       ]
       )
    

    Now I have 3 Stfl Class and every Stful has also TabBarView with some tabs, I am going to use here Stful3 Tab to make it simple

    Stful3() =>
        late final TabController _controller2 = TabController( length: 3, vsync: this,initialIndex: 0);
         bottom:  TabBar(
          controller: _controller2,
        
         tabs: const [
         Tab(text: "page1",),
        Tab(text: "page2",),
        Tab(text: "page3",),
        
         ],
        ),
        
            TabBarView(
            controller: _controller2
            children: [
            page1()
            page2()
            page3()
           ]
           )
    

    Now lets say i am in page 1 and scrolling free with page1 and page3 but when i access to extent swip right or left where there is no tabs in current TabBarView it does not moving me to other tabs which they are in the main TabBarView .

    does it possible in flutter frame work ? How can achieve this ?

    EDIT

    here is the full code

    import 'package:flutter/material.dart';
    
    class MyMainTabVarView extends StatefulWidget {
      const MyMainTabVarView({Key? key}) : super(key: key);
    
      @override
      _MyMainTabVarViewState createState() => _MyMainTabVarViewState();
    }
    
    class _MyMainTabVarViewState extends State<MyMainTabVarView> with SingleTickerProviderStateMixin{
    
      late final TabController controllerForMainTabVarView = TabController( length: 3, vsync: this,initialIndex: 0 );
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
    
          backgroundColor: Colors.blue,
          body: Column(
            children:  [
              Expanded(
                child: TabBarView(
                  controller: controllerForMainTabVarView,
                  children: const [
                    MyStful1(),
                    MyStful2(),
                    MyStful3(),
                  ],
                ),
              ),
              TabBar( // here i am use TabBar at the bottom of the screen instead of bottom Navigation Bar
                controller:controllerForMainTabVarView,
                tabs: const [
                  Tab(text: "My Stful 1",),
                  Tab(text: "My Stful 2",),
                  Tab(text: "My Stful 3",),
                ],
              )
            ],
          ),
        );
      }
    }
    
    
    
    class MyStful1 extends StatefulWidget {
      const MyStful1({Key? key}) : super(key: key);
    
      @override
      _MyStful1State createState() => _MyStful1State();
    }
    
    class _MyStful1State extends State<MyStful1> with SingleTickerProviderStateMixin{
    
      late final TabController controllerForMyStful1 = TabController( length: 2, vsync: this,initialIndex: 0 );
    
      @override
      Widget build(BuildContext context) {
        return  Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller:controllerForMyStful1,
              tabs: const [
                Tab(text: "Page1",),
                Tab(text: "Page2",),
              ],
            ),
          ),
          body: TabBarView(
            controller: controllerForMyStful1,
            children: const [
              Center(child: Text('Page1')),
              Center(child: Text('Page2')),
            ],
          ),
        );
      }
    }
    
    
    
    class MyStful2 extends StatefulWidget {
      const MyStful2({Key? key}) : super(key: key);
    
      @override
      _MyStful2State createState() => _MyStful2State();
    }
    
    class _MyStful2State extends State<MyStful2> with SingleTickerProviderStateMixin{
    
      late final TabController controllerForMyStful2 = TabController( length: 2, vsync: this,initialIndex: 0 );
    
      @override
      Widget build(BuildContext context) {
        return  Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller:controllerForMyStful2,
              tabs: const [
                Tab(text: "Page1",),
                Tab(text: "Page2",),
              ],
            ),
          ),
          body: TabBarView(
            controller: controllerForMyStful2,
            children: const [
              Center(child: Text('Page1')),
              Center(child: Text('Page2')),
            ],
          ),
        );
      }
    }
    
    
    class MyStful3 extends StatefulWidget {
      const MyStful3({Key? key}) : super(key: key);
    
      @override
      _MyStful3State createState() => _MyStful3State();
    }
    
    class _MyStful3State extends State<MyStful3>with SingleTickerProviderStateMixin {
    
      late final TabController controllerForMyStful3 = TabController( length: 2, vsync: this,initialIndex: 0 );
    
      @override
      Widget build(BuildContext context) {
        return  Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller:controllerForMyStful3,
              tabs: const [
                Tab(text: "Page1",),
                Tab(text: "Page2",),
              ],
            ),
          ),
          body: TabBarView(
            controller: controllerForMyStful3,
            children: const [
              Center(child: Text('Page1')),
              Center(child: Text('Page2')),
            ],
          ),
        );
      }
    }
    
    • Yeasin Sheikh
      Yeasin Sheikh about 2 years
      Can you provide full sample widget?
    • Mohammed Hamdan
      Mohammed Hamdan about 2 years
      done .. please take a look :) @Yasin Sheikh
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    Just Wow , thanks a lot ..truly i mean it , 100% Yeasin Sheikh
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    but can i use this approach with tabbarview ? like my question ?
  • Yeasin Sheikh
    Yeasin Sheikh about 2 years
    Yes, the logic on the same way I believe, you can test it.
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    i tested it with tabBarView but still the glow prevent me to navigate to other tab
  • Yeasin Sheikh
    Yeasin Sheikh about 2 years
    can you do a recheck, top TabBar or bottom?
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    i just replace stful into page view instead of yours tabs
  • Yeasin Sheikh
    Yeasin Sheikh about 2 years
    nope. that's not all, I am using PageView as main body, please do recheck the snippet flow
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    3 hours trying to chick it and handle . couldn't find way
  • Yeasin Sheikh
    Yeasin Sheikh about 2 years
    Sorry bro, I think I'm not quite understanding the issue.
  • Mohammed Hamdan
    Mohammed Hamdan about 2 years
    i am the one who sorry , and you solved my problem but i am the one who can't handle your example with tabbarview , you told me it same logic but i couldn't handle this .. if you edit your answer and use same logic with what you said to me that is work with tabbarview would be extramly thankful