简体   繁体   中英

How to scroll to next tab using TabBarView into TabBarView

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')),
        ],
      ),
    );
  }
}

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",
              ),
            ],
          )
        ],
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM