Flutter: Changing the current tab in tab bar view using a button

后端 未结 5 1841
北荒
北荒 2020-12-12 15:24

I am creating an app that contains a tab bar on its homepage. I want to be able to navigate to one of the tabs using my FloatingActio

相关标签:
5条回答
  • 2020-12-12 15:38
    class Tab bar
    
        class TabBarScreen extends StatefulWidget {
          TabBarScreen({Key key}) : super(key: key);
        
          @override
          _TabBarScreenState createState() => _TabBarScreenState();
        }
        
        final List<Tab> tabs = <Tab>[
          Tab(text: 'Page1'),
          Tab(text: 'Page2'),
        ];
        
        class _TabBarScreenState extends State<TabBarScreen> with SingleTickerProviderStateMixin {
        
          TabController tabController;
        
          @override
          void initState() {
            super.initState();
            tabController = new TabController(vsync: this, length: tabs.length);
          }
        
          @override
          void dispose() {
            tabController.dispose();
            super.dispose();
          }
        
          @override
          Widget build(BuildContext context) {
            return DefaultTabController(
              length: 2,
              child: Scaffold(
                backgroundColor: Theme.of(context).primaryColor,
                appBar: AppBar(
                  backgroundColor: Theme.of(context).primaryColor,
                  centerTitle: true,
                  shape: Border(bottom: BorderSide(color: Colors.white)),
                  title: Text("Tab Bar",),
                  bottom: TabBar(
                    controller: tabController,
                    tabs: tabs,
                    indicatorWeight: 5,
                    indicatorColor: Colors.white,
                    labelColor: Colors.white,
                  ),
                ),
                body: TabBarView(
                  controller: tabController,
                  children: [
                    PageOneScreen(controller: tabController),
                    PageTwoScreen(controller: tabController),
                  ],
                ),
              ),
            );
          }
        }
    
    class PageOne
    
        class PageOneScreen extends StatefulWidget {
        @override
        _PageOneScreenState createState() => _PageOneScreenState();
    
           PageOneScreen({controller}) {
              tabController = controller;
           }
        }
    
        TabController tabController;
    
        class _PageOneScreenState extends State<PageOneScreen> {
          @override
          Widget build(BuildContext context) {
            return Column(
              children: [
                RaisedButton(
                  onPressed: () {
                    tabController.animateTo(1); // number : index page
                  },
                  child: Text(
                    "Go To Page 2",
                  ),
                ),
              ],
            );
          }
        }
    
    0 讨论(0)
  • 2020-12-12 15:54

    chemamolin's answer above is correct, but for additional clarification/tip, if you want to call your tabcontroller "from anywhere", also make sure the tabcontroller is not a private property of the class by removing the underscore, otherwise the distant class will not be able to see the tabcontroller with the example provided even when using the GlobalKey.

    In other words, change

    TabController _tabController;
    

    to:

    TabController tabController;
    

    and change

    MyApp._myTabbedPageKey.currentState._tabController.animateTo(...);
    

    to:

    MyApp._myTabbedPageKey.currentState.tabController.animateTo(...);
    

    and everywhere else you reference tabcontroller.

    0 讨论(0)
  • 2020-12-12 15:57

    You can use TabController:

    TabController _controller = TabController(
      vsync: this,
      length: 3,
      initialIndex: 0,
    );
    
    _controller.animateTo(_currentTabIndex);
    
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _controller,
          tabs: [
            ...
          ],
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: [
          ...
        ],
      ),
    );
    

    And than, setState to update screen:

    int _currentTabIndex = 0;
    
    setState(() {
      _currentTabIndex = 1;
    });
    
    0 讨论(0)
  • 2020-12-12 15:59

    You need to get the TabBar controller and call its animateTo() method from the button onPressed() handle.

    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          home: new MyTabbedPage(),
        );
      }
    }
    
    class MyTabbedPage extends StatefulWidget {
      const MyTabbedPage({Key key}) : super(key: key);
    
      @override
      _MyTabbedPageState createState() => new _MyTabbedPageState();
    }
    
    class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
      final List<Tab> myTabs = <Tab>[
        new Tab(text: 'LEFT'),
        new Tab(text: 'RIGHT'),
      ];
    
      TabController _tabController;
    
      @override
      void initState() {
        super.initState();
        _tabController = new TabController(vsync: this, length: myTabs.length);
      }
    
      @override
      void dispose() {
        _tabController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Tab demo"),
            bottom: new TabBar(
              controller: _tabController,
              tabs: myTabs,
            ),
          ),
          body: new TabBarView(
            controller: _tabController,
            children: myTabs.map((Tab tab) {
              return new Center(child: new Text(tab.text));
            }).toList(),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: () => _tabController.animateTo((_tabController.index + 1) % 2), // Switch tabs
            child: new Icon(Icons.swap_horiz),
          ),
        );
      }
    }
    

    If you use a GlobalKey for the MyTabbedPageState you can get the controller from any place, so you can call the animateTo() from any button.

    class MyApp extends StatelessWidget {
      static final _myTabbedPageKey = new GlobalKey<_MyTabbedPageState>();
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          home: new MyTabbedPage(
            key: _myTabbedPageKey,
          ),
        );
      }
    }
    

    You could call it from anywhere doing:

    MyApp._myTabbedPageKey.currentState._tabController.animateTo(...);

    0 讨论(0)
  • 2020-12-12 16:00

    If you want to jump to a specific page, you can use

    PageController.jumpToPage(int)
    

    However if you need animation, you'd use

    PageController.animateToPage(page, duration: duration, curve: curve)
    

    Simple example demonstrating it.

    // create a PageController
    final _controller = PageController();
    bool _shouldAnimate = true; // whether we animate or jump
    
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            if (_shouldAnimate) {
              // animates to page1 with animation
              _controller.animateToPage(1, duration: Duration(seconds: 1), curve: Curves.easeOut);  
            } else {
              // jump to page1 without animation
              _controller.jumpToPage(1);
            }
          },
        ),
        body: PageView(
          controller: _controller, // assign it to PageView
          children: <Widget>[
            FlutterLogo(colors: Colors.orange), // page0
            FlutterLogo(colors: Colors.green), // page1
            FlutterLogo(colors: Colors.red), // page2
          ],
        ),
      );
    }
    
    0 讨论(0)
提交回复
热议问题