标签的动态数量

Dynamic number of tabs

我的设计如上,我的标签栏在 BottomNavigationBar 内,我想将标签栏放在我的 BottomNavigationBar 菜单中。问题是,我不想嵌套脚手架,也不想使用 TabController,因为我的选项卡是动态的,选项卡长度可以根据用户添加而减少或增加。如果我使用 TabController 并在 initState 中定义它,则选项卡不能是 increase/decrease 因为在 initState 中只定义一次值。

我该怎么做?

My expectation similiar in below example , when i adding tab and tabMenu it will increase . But get this error

The following assertion was thrown building TabBar(dirty, dependencies: [_InheritedTheme,
_LocalizationsScope-[GlobalKey#a56a4]], state: _TabBarState#fb337):
Controller's length property (2) does not match the number of tabs (3) present in TabBar's tabs
property.
The relevant error-causing widget was:
  TabBar

虚拟示例


class TaskScreen extends StatefulWidget {
  @override
  _TaskScreenState createState() => _TaskScreenState();
}

class _TaskScreenState extends State<TaskScreen> with SingleTickerProviderStateMixin {
  TabController _tabController;

  final List<Tab> _tab = [
    Tab(text: 'Sunday'),
    Tab(text: 'Monday'),
  ];
  final List<Widget> _tabMenu = [
    Text('This is Sunday'),
    Text('This is Monday'),
  ];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: _tab.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        FlatButton(
            onPressed: () {
              setState(() {
                _tab.add(Tab(
                  text: '1',
                ));
                _tabMenu.add(Text('1'));
              });
              print('tab ${_tab.length}');
              print('tabMenu ${_tabMenu.length}');
            },
            child: Text('add')),
        Container(
          color: colorPallete.primaryColor,
          padding: EdgeInsets.only(top: sizes.statusBarHeight(context)),
          child: TabBar(
            tabs: _tab.map((e) => e).toList(),
            controller: _tabController,
          ),
        ),
        Expanded(
          child: TabBarView(
            children: _tabMenu.map((e) => e).toList(),
            controller: _tabController,
          ),
        )
      ],
    );
  }
}

使用 TickerProviderStateMixin 而不是 SingleTickerProviderStateMixin 并在更改标签编号时更改 TabController

如果您的所有选项卡都没有 space,请添加 isScrollable: true

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: SafeArea(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return TaskScreen();
  }
}

class TaskScreen extends StatefulWidget {
  @override
  _TaskScreenState createState() => _TaskScreenState();
}

class _TaskScreenState extends State<TaskScreen> with TickerProviderStateMixin {
  TabController _tabController;

  final List<Tab> _tab = [
    Tab(text: 'Sunday'),
    Tab(text: 'Monday'),
  ];
  final List<Widget> _tabMenu = [
    Text('This is Sunday'),
    Text('This is Monday'),
  ];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: _tab.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        FlatButton(
            onPressed: () {
              setState(() {
                _tab.add(
                  Tab(
                    text: '1',
                  ),
                );
                _tabMenu.add(
                  Text('1'),
                );
                _tabController =
                    TabController(length: _tab.length, vsync: this);
              });
              print('tab ${_tab.length}');
              print('tabMenu ${_tabMenu.length}');
            },
            child: Text('add')),
        Container(
          color: Colors.blue,
          padding: EdgeInsets.only(top: 10),
          child: TabBar(
            // isScrollable: true, 
            tabs: _tab.map((e) => e).toList(),
            controller: _tabController,
          ),
        ),
        Expanded(
          child: TabBarView(
            children: _tabMenu.map((e) => e).toList(),
            controller: _tabController,
          ),
        )
      ],
    );
  }
}