颤动:使用按钮更改标签栏视图中的当前选项卡

时间:2018-06-16 12:12:02

标签: dart flutter

我正在创建一个在其主页上包含标签栏的应用。我希望能够导航到其中一个标签使用我的class DomaineDashboardFragment extends Fragment{ public void refresh(Data newData){ //update dash board views here } } // I assume you are updating fragment data from the activity class MainActivity extends Activity{ private Fragment dashBoardFrag; public void onDataUpdate(Data newData){ if(fragment.isAdded()){ fragment.refresh(newData) }else{ //pass data through bundle, fragment is not attached. } } } 。另外,我想保留导航到该选项卡的默认方法,即通过在屏幕上滑动或单击选项卡。

我也想知道如何将该标签链接到其他按钮。

以下是我的主页的截图。

Homepage with navigation tabs and floating action button

7 个答案:

答案 0 :(得分:19)

您需要获取TabBar控制器并从按钮animateTo()句柄调用其onPressed()方法。

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

如果GlobalKey使用MyTabbedPageState,您可以从任何地方获取控制器,因此您可以从任意按钮拨打animateTo()

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

您可以从任何地方拨打电话:

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

答案 1 :(得分:3)

我来晚了,但希望有人能从中受益。只需将此行添加到按钮的onPressed上,并确保将索引号更改为您的首选索引:

DefaultTabController.of(context).animateTo(1);

答案 2 :(得分:1)

您可以使用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: [
      ...
    ],
  ),
);

然后,setState更新屏幕:

int _currentTabIndex = 0;

setState(() {
  _currentTabIndex = 1;
});

答案 3 :(得分:1)

DefaultTabController(
              length: 4,
              initialIndex: 0,
              child: TabBar(
                tabs: [
                  Tab(
                    child: Text(
                      "People",
                      style: TextStyle(
                        color: Colors.black,
                      ),
                    ),
                  ),
                  Tab(
                    child: Text(
                      "Events",
                      style: TextStyle(
                        color: Colors.black,
                      ),
                    ),
                  ),
                  Tab(
                    child: Text(
                      "Places",
                      style: TextStyle(
                        color: Colors.black,
                      ),
                    ),
                  ),
                  Tab(
                    child: Text(
                      "HashTags",
                      style: TextStyle(
                        color: Colors.black,
                      ),
                    ),
                  ),
                ],
              ),
            )

答案 4 :(得分:0)

如果要跳到特定页面,可以使用

PageController.jumpToPage(int)

但是,如果您需要动画,则可以使用

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

演示它的简单示例。

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

答案 5 :(得分:0)

chemamolin's answer above是正确的,但是为了进一步说明/提示,如果您想“从任何地方”调用tabcontroller,还应通过删除来确保tabcontroller不是该类的私有属性。下划线,否则,即使使用GlobalKey,遥远的类也无法看到带有提供的示例的tabcontroller。

换句话说,更改

TabController _tabController;

至:

TabController tabController;

并更改

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

至:

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

以及其他引用tabcontroller的地方。

答案 6 :(得分:0)

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