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

Sun*_*tam 20 dart flutter

我正在创建一个在其主页上包含标签栏的应用程序.我希望能够使用我的导航到其中一个标签.另外,我想保留导航到该选项卡的默认方法,即通过在屏幕上滑动或单击选项卡.FloatingActionButton

我还想知道如何将该选项卡链接到其他按钮.

这是我的主页的屏幕截图.

主页带有导航标签和浮动操作按钮

che*_*ins 33

您需要获取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),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用a 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,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以从任何地方调用它:

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

  • 但如何在它们之间传递数据呢? (3认同)

Glo*_*der 27

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

DefaultTabController.of(context).animateTo(1);
Run Code Online (Sandbox Code Playgroud)

  • 我一直喜欢单行解决方案:)非常感谢! (4认同)
  • 对我不起作用据说在 null 上调用了方法“animateTo”在 null 上调用。接收者:空 (3认同)
  • @OmarEssam 请在 `DefaultTabController(length: 3,child: Builder(builder: (BuildContext context) { // here before return }` 中使用它 (3认同)

小智 6

您可以使用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: [
      ...
    ],
  ),
);
Run Code Online (Sandbox Code Playgroud)

然后,setState更新屏幕:

int _currentTabIndex = 0;

setState(() {
  _currentTabIndex = 1;
});
Run Code Online (Sandbox Code Playgroud)

  • 确保在“build()”方法中添加“_controller”的定义。否则,“vsync: this”会出错。 (2认同)

小智 5

chemamolin 上面的答案是正确的,但是为了额外的说明/提示,如果您想“从任何地方”调用 tabcontroller,还要通过删除下划线来确保 tabcontroller 不是该类的私有属性,否则远程类将不会即使使用 GlobalKey 也能够通过提供的示例查看选项卡控制器。

换句话说,改变

TabController _tabController;
Run Code Online (Sandbox Code Playgroud)

到:

TabController tabController;
Run Code Online (Sandbox Code Playgroud)

并改变

MyApp._myTabbedPageKey.currentState._tabController.animateTo(...);
Run Code Online (Sandbox Code Playgroud)

到:

MyApp._myTabbedPageKey.currentState.tabController.animateTo(...);
Run Code Online (Sandbox Code Playgroud)

以及您引用 tabcontroller 的其他地方。