如何在Flutter中获取当前选项卡索引

时间:2018-05-01 20:27:57

标签: flutter tabcontrol flutter-layout

在颤动中实现标签布局简单明了。这是官方documentation

中的一个简单示例
import 'package:flutter/material.dart';

void main() {
  runApp(new TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new DefaultTabController(
        length: 3,
        child: new Scaffold(
          appBar: new AppBar(
            bottom: new TabBar(
              tabs: [
                new Tab(icon: new Icon(Icons.directions_car)),
                new Tab(icon: new Icon(Icons.directions_transit)),
                new Tab(icon: new Icon(Icons.directions_bike)),
              ],
            ),
            title: new Text('Tabs Demo'),
          ),
          body: new TabBarView(
            children: [
              new Icon(Icons.directions_car),
              new Icon(Icons.directions_transit),
              new Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  }
}

但事情就是这样,我希望得到活动标签索引,以便我可以在某些标签上应用某些逻辑。我搜索文档但我无法弄明白。你们能帮帮忙吗?

9 个答案:

答案 0 :(得分:10)

And的重点是让它自己管理标签。

如果您想要一些自定义标签管理,请改用TabController。 使用DefaultTabController,您可以访问更多信息,包括当前索引。

TabController

答案 1 :(得分:3)

您可以添加一个侦听器来侦听以下选项卡中的更改

tabController = TabController(vsync: this, length: 4)
   ..addListener(() {
setState(() {
  switch(tabController.index) {
    case 0:
      // some code here
    case 1:
     // some code here
  }
  });
});

答案 2 :(得分:3)

使用DefaultTabController,无论用户通过标签栏上的滑动还是点击来更改标签,都可以轻松获取当前索引。

重要提示:您必须将Scaffold包装在Builder内,然后才能在DefaultTabController.of(context).index内使用Scaffold来检索标签索引。

示例:

DefaultTabController(
    length: 3,
    child: Builder(builder: (BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Home'),
          bottom: TabBar(
              isScrollable: true,
              tabs: [Text('0'), Text('1'), Text('2')]),
        ),
        body: _buildBody(),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            print(
                'Current Index: ${DefaultTabController.of(context).index}');
          },
        ),
      );
    }),
  ),

答案 3 :(得分:2)

在这种情况下,使用StatefulWidgetState不是一个好主意。

您可以通过DefaultTabController.of(context).index;获取当前索引。

遵循代码:

...
appBar: AppBar(
  bottom: TabBar(
    tabs: [
      Tab(~), Tab(~)
    ]
  ),
  actions: [
    // At here you have to get `context` from Builder.
    // If you are not sure about this, check InheritedWidget document.
    Builder(builder: (context){
      final index = DefaultTabController.of(context).index;   
      // use index at here... 
    })
  ]
)

答案 4 :(得分:1)

通过TabBar的onTap事件选择选项卡时,可以访问当前索引。

TabBar(
    onTap: (index) {
      //your currently selected index
    },

    tabs: [
      Tab1(),
      Tab2(),
    ]);

答案 5 :(得分:0)

通过RémiRousselet的示例,您可以做到,代码如下:

_tabController.index

这将返回TabBarView位置的当前索引

答案 6 :(得分:0)

只需在TabController上应用侦听器即可。

// within your initState() method
_tabController.addListener(_setActiveTabIndex);

void _setActiveTabIndex() {
  _activeTabIndex = _tabController.index;
}

答案 7 :(得分:0)

新的工作解决方案

我建议您使用 TabController 进行更多自定义。要获得活动标签索引,您应该使用 _tabController.addListener_tabController.indexIsChanging

使用此完整代码片段


class CustomTabs extends StatefulWidget {
  final Function onItemPressed;

  CustomTabs({
    Key key,
    this.onItemPressed,
  }) : super(key: key);

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

class _CustomTabsState extends State<CustomTabs>
    with SingleTickerProviderStateMixin {

  final List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  TabController _tabController;
  int _activeIndex = 0;
  
  @override
  void initState() {
    super.initState();
    _tabController = TabController(
      vsync: this,
      length: myTabs.length,
    );
  }

  @override
  void dispose() {
    super.dispose();
    _tabController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    _tabController.addListener(() {
      if (_tabController.indexIsChanging) {
        setState(() {
          _activeIndex = _tabController.index;
        });
      }
    });
    return Container(
      color: Colors.white,
      child: TabBar(
        controller: _tabController,
        isScrollable: true,
        indicatorPadding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
        indicator: BoxDecoration(
            borderRadius: BorderRadius.circular(10.0), color: Colors.green),
        tabs: myTabs
            .map<Widget>((myTab) => Tab(
                  child: Container(
                    width: width / 3 -
                        10, // - 10 is used to make compensate horizontal padding
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10.0),
                      color:
                          _activeIndex == myTabs.indexOf(myTab)
                              ? Colors.transparent
                              : Color(0xffA4BDD4),
                    ),
                    margin:
                        EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0),
                    child: Align(
                      alignment: Alignment.center,
                      child: Text(
                        myTab.text,
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  ),
                ))
            .toList(),
        onTap: widget.onItemPressed,
      ),
    );
  }
}

答案 8 :(得分:-2)

此代码将为您提供活动标签的索引,还保存标签索引以备将来使用,当您返回标签页时,将显示上一个活动页。

import 'package:flutter/material.dart';

    void main() {
      runApp(new TabBarDemo());
    }

    class TabBarDemo extends StatelessWidget {


      TabScope _tabScope = TabScope.getInstance();

      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new DefaultTabController(
            length: 3,
            index: _tabScope.tabIndex, // 
            child: new Scaffold(
              appBar: new AppBar(
                bottom: new TabBar(
                  onTap: (index) => _tabScope.setTabIndex(index),  //current tab index
                  tabs: [
                    new Tab(icon: new Icon(Icons.directions_car)),
                    new Tab(icon: new Icon(Icons.directions_transit)),
                    new Tab(icon: new Icon(Icons.directions_bike)),
                  ],
                ),
                title: new Text('Tabs Demo'),
              ),
              body: new TabBarView(
                children: [
                  new Icon(Icons.directions_car),
                  new Icon(Icons.directions_transit),
                  new Icon(Icons.directions_bike),
                ],
              ),
            ),
          ),
        );
      }
    }

    class TabScope{ // singleton class
      static TabScope _tabScope;
      int tabIndex = 0;

      static TabScope getInstance(){
        if(_tabScope == null) _tabScope = TabScope();

        return _tabScope;
      }
      void setTabIndex(int index){
        tabIndex = index;
      }
    }