效果:用户可自定义Tabbar的长度和排序,通过滑动或点击Tabbar进行请求接口渲染不同的页面

问题:让用户自定义Tabbar的长度,当用户删除Tabbar的一项时出现报错

1
Controller's length property (5) does not match the number of tabs (4) prese

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
TabController tabController;  

@override
void initState() {
// TODO: implement initState
super.initState();
tabController = TabController(
length: websiteList.length, vsync: this);
tabController..addListener(() {
if(tabController.indexIsChanging){
print(tabController.index.toString());
}
});

}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
bottom: TabBar(
indicatorColor: Color(0xFFFE1483),
labelColor: Color(0xFFFE1483),
controller: tabController,
unselectedLabelColor: Colors.black54,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
tabs: TabList()),
),
body: TabBarView(
controller: tabController,
children: CardList(),
),);

initState(){}只初始化一次,当用户删除websiteList中的值时,websiteList.length发生变化,用户再次进入该界面就会出现报错
解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@override  
void initState() {
// TODO: implement initState
super.initState();
}

@override
Widget build(BuildContext context) {
return DefaultTabController(
length: websiteList.length,
child: Builder(
builder: (BuildContext context){
final TabController tabController = DefaultTabController.of(context);
tabController.addListener(() {
if (tabController.index.toDouble() ==
tabController.animation.value) {
print(tabController.index.toString());
}
});
return Scaffold(
appBar: AppBar(
elevation: 2,
bottom: TabBar(
indicatorColor: Color(0xFFFE1483),
labelColor: Color(0xFFFE1483),
unselectedLabelColor: Colors.black54,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
tabs: TabList()),
),
body: TabBarView(
children: CardList(),
),
);
},
)
);

通过DefaultTabController解决因websiteList发生变化出现的问题,通过Builder()进行监听用户是否点击和滑动tabbar,即可解决问题