我观察到考虑不同的 scnarios。
- widgetList 为空,正在使用 add
List<TabItem> widgetList = [];
..
// added this count to check which widget is calling init or dispose
widgetList.add(TabItem("Added", AWidget(count: count)));
- 初始:无小部件
- 第一次按下:添加小部件(打印 init 0)
- 第二次按下:添加另一个小部件(打印 init1 dispose1)
- 进一步印刷:不打印任何东西
- widgetList 包含 3 个选项卡并使用添加
List<TabItem> widgetList = [];
..
// added this count to check which widget is calling init or dispose
List<TabItem> widgetList = [
TabItem("Test", const AWidget(count: 0)),
TabItem("Test", const AWidget(count: 1)),
TabItem("Test", const AWidget(count: 2))
];
- 初始:包含 2 个选项卡(打印 init0)
- 进一步印刷:不打印任何东西
- widgetList 为空,正在使用插入
List<TabItem> widgetList = [];
..
// added this count to check which widget is calling init or dispose
widgetList.insert(count, TabItem("Added", AWidget(count: count)));
- 初始:无小部件
- 第一次按下:添加小部件(打印 init 0)
- 第二次按下:添加另一个小部件(打印 init1 dispose1)
- 进一步印刷:不打印任何东西
- widgetList 包含 3 个选项卡并使用插入功能
List<TabItem> widgetList = [
TabItem("Test", const AWidget(count: 0)),
TabItem("Test", const AWidget(count: 1)),
TabItem("Test", const AWidget(count: 2))
];
..
// added this count to check which widget is calling init or dispose
widgetList.insert(count, TabItem("Added", AWidget(count: count)));
- 初始:包含 2 个选项卡(打印 init0)
- 进一步印刷:不打印任何东西
考虑所有 4 种情况:您只获得一次 init 和 dispose,即当只有 1 个选项卡并且您正在添加第 2 个选项卡时。这是因为添加的选项卡在添加到TabBar 时会初始化并立即释放。
我假设标签栏在添加第二个标签时初始化(预期的)功能,然后在添加其余标签时正常工作。
通常是两个或多个 Tab 小部件的列表。
我的假设是基于here 的这句话。
我可以肯定地说,这种行为是由 TabBar 而不是 List 引起的。
add 和 insert 工作方式相似,对这种行为没有任何影响。
同时,当您切换到其他选项卡时,假设是从 0->1。然后打印,init1,dispose0。这是因为当离开小部件时,它会初始化新的小部件并处理以前使用的小部件(就像导航活动一样)。
我还想指出一件事。考虑使用add 而不是insert,除非由于时间复杂性需要。
我用来测试的完整代码(包括计数):
import 'package:flutter/material.dart';
class TabItem {
final String title;
final Widget widget;
TabItem(this.title, this.widget);
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
Key? key,
}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<TabItem> widgetList = [];
int _count = 0; // use 3 when using below commented code
// List<TabItem> widgetList = [
// TabItem("Test", const AWidget(count: 0)),
// TabItem("Test", const AWidget(count: 1)),
// TabItem("Test", const AWidget(count: 2))
// ];
void _incrementCounter(int count) {
setState(() {
widgetList.add(TabItem("Added", AWidget(count: count)));
// widgetList.insert(count, TabItem("Added", AWidget(count: count)));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Main Page'),
),
body: DefaultTabController(
length: widgetList.length,
child: Builder(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Press floating button to add to list"),
bottom: TabBar(
isScrollable: true,
tabs: <Tab>[
for (var i in widgetList)
Tab(
text: i.title,
)
],
),
),
body: TabBarView(
children: [for (var i in widgetList) i.widget]),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter(_count++);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class AWidget extends StatefulWidget {
const AWidget({
Key? key,
this.count=0,
}) : super(key: key);
final int count;
@override
_AWidgetState createState() => _AWidgetState();
}
class _AWidgetState extends State<AWidget> {
@override
void initState() {
super.initState();
print('initState ${widget.count}');
}
@override
void dispose() {
print('dispose ${widget.count}');
super.dispose();
}
@override
Widget build(BuildContext context) {
return Text('something ${widget.count}');
}
}