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

Flutter 如何在flatter中获取当前选项卡索引,flutter,tabcontrol,flutter-layout,Flutter,Tabcontrol,Flutter Layout,在颤振中,实现选项卡布局简单明了。这是一个来自官方的简单例子: 但问题是,我想得到活动选项卡索引,这样我就可以在某些选项卡上应用一些逻辑。我搜索了文档,但没能找到它。你们能帮个忙吗?DefaultTabController的全部功能就是让它自己管理选项卡 如果需要一些自定义选项卡管理,请改用。 使用TabController可以访问更多信息,包括当前索引 class MyTabbedPage extends StatefulWidget { const MyTabbedPage({Key k

在颤振中,实现选项卡布局简单明了。这是一个来自官方的简单例子:


但问题是,我想得到活动选项卡索引,这样我就可以在某些选项卡上应用一些逻辑。我搜索了文档,但没能找到它。你们能帮个忙吗?

DefaultTabController的全部功能就是让它自己管理选项卡

如果需要一些自定义选项卡管理,请改用。 使用
TabController
可以访问更多信息,包括当前索引

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(
        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(),
      ),
    );
  }
}
类MyTabbedPage扩展StatefulWidget{
constmytabbedpage({Key}):super(Key:Key);
@凌驾
_MyTabbedPageState createState()=>new_MyTabbedPageState();
}
类_MyTabbedPageState扩展状态
使用SingleTickerProviderStateMixin{
最终列表myTabs=[
新建选项卡(文本:“左”),
新建选项卡(文本:“右”),
];
TabController\u TabController;
@凌驾
void initState(){
super.initState();
_tabController=newtabcontroller(vsync:this,length:myTabs.length);
}
@凌驾
无效处置(){
_tabController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
底部:新选项卡栏(
控制器:\ tab控制器,
标签:我的标签,
),
),
正文:新选项卡视图(
控制器:\ tab控制器,
子项:myTabs.map((选项卡){
返回新中心(子项:新文本(tab.Text));
}).toList(),
),
);
}
}

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

您可以通过
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... 
    })
  ]
)


多亏了Rémi Rousselet的例子,您可以这样做,代码如下:

_tabController.index

这将返回TabBarView位置的当前索引。当TabBar的onTap事件选择选项卡时,您可以访问当前索引

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

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

只需在TabController上应用一个侦听器

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

void _setActiveTabIndex() {
  _activeTabIndex = _tabController.index;
}
此代码将为您提供活动选项卡的索引,还将保存选项卡索引以供将来使用,当您返回到选项卡页面时,将显示上一个活动页面


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

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

使用
DefaultTabController
您可以轻松获取当前索引,无论用户是通过滑动还是点击选项卡栏上的来更改选项卡

重要提示:必须将
Scaffold
包装在
Builder
中,然后可以使用
DefaultTabController.of(context).index
inside
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}');
          },
        ),
      );
    }),
  ),

新的工作解决方案

我建议您使用
TabController
进行更多定制。要获取活动选项卡索引,应使用
\u tabController.addListener
\u 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,
      ),
    );
  }
}

类CustomTabs扩展StatefulWidget{
最终功能未被压缩;
自定义选项卡({
关键点,
这使我感到压抑,
}):super(key:key);
@凌驾
_CustomTabsState createState();
}
类\u CustomTabsState扩展状态
使用SingleTickerProviderStateMixin{
最终列表myTabs=[
选项卡(文本:“左”),
选项卡(文本:“右”),
];
TabController\u TabController;
int _activeIndex=0;
@凌驾
void initState(){
super.initState();
_tabController=tabController(
vsync:这个,,
长度:myTabs.length,
);
}
@凌驾
无效处置(){
super.dispose();
_tabController.dispose();
}
@凌驾
小部件构建(构建上下文){
double width=MediaQuery.of(context).size.width;
_tabController.addListener((){
if(tab controller.indexIsChanging){
设置状态(){
_activeIndex=\u tabController.index;
});
}
});
返回容器(
颜色:颜色,白色,
孩子:TabBar(
控制器:\ tab控制器,
isScrollable:是的,
指示器添加:边缘组。对称(水平:5.0,垂直:5.0),
指标:盒子装饰(
边界半径:边界半径。圆形(10.0),颜色:颜色。绿色),
标签:我的标签
.map((myTab)=>Tab(
子:容器(
宽度:宽度/3-
10,//-10用于补偿水平填充
装饰:盒子装饰(
边界半径:边界半径。圆形(10.0),
颜色:
_activeIndex==myTabs.indexOf(myTab)
?颜色。透明
:颜色(0xffA4BDD4),
),
保证金:
边缘组。对称(水平:5.0,垂直:5.0),
子对象:对齐(
对齐:对齐.center,
子:文本(
myTab.text,
样式:TextStyle(颜色:Colors.white),
),
),
),
))
.toList(),
onTap:widget.onimpressed,
),
);
}
}

在本例中,如何获取索引??我尝试添加列表器,但在构建特定选项卡视图后,侦听器正在打印索引。我想在构建特定选项卡布局之前获取索引。有什么想法吗?仅限状态?嘿@sarveshchavan有什么解决方案吗?要获取选项卡的索引,只需执行
\tabController.index
包装整个选项卡即可
Scaffold
在一个
Builder
中为我工作。谢谢,这就是我一直在寻找的。这应该是可以接受的答案。需要lea的最简单解决方案
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}');
          },
        ),
      );
    }),
  ),

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