(菜鸟学习记录)
直接上图上代码,代码部分有注释,莫有的自己百度(留言也可以);
效果图.png
class TestDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _TestDemoState();
}
}
class _TestDemoState extends State<TestDemo>
with SingleTickerProviderStateMixin {
TabController mController;
List<String> tabTitles;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _appBarView(),
body: _tabBarView(),
);
}
@override
void dispose() {
super.dispose();
mController.dispose();
}
@override
void initState() {
super.initState();
tabTitles = [
"tab1",
"tab2",
"tab3",
"tab4",
"tab5",
"tab6",
"tab7",
"tab8",
"tab9",
];
mController = TabController(
length: tabTitles.length,
vsync: this,
);
}
Widget _appBarView() {
return AppBar(
title: Text("TabBar & TabBarView",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)),
elevation: 0,
bottom: _tabBar(),
);
}
Widget _tabBar() {
return TabBar(
//设置tab是否可水平滑动
isScrollable: true,
//控制器
controller: mController,
//设置tab文字得类型
labelStyle: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
//设置tab选中得颜色
labelColor: Colors.black,
//设置tab未选中得颜色
unselectedLabelColor: Colors.black45,
//设置自定义tab的指示器,CustomUnderlineTabIndicator
//若不需要自定义,可直接通过
//indicatorColor 设置指示器颜色
//indicatorWight 设置指示器厚度
//indicatorPadding
//indicatorSize 设置指示器大小计算方式
indicator: CustomUnderlineTabIndicator(
strokeCap: StrokeCap.round,
insets: EdgeInsets.only(left: 15, right: 15),
borderSide: BorderSide(width: 4.0, color: Colors.red)),
tabs: tabTitles.map((item) {
return Tab(text: item);
}).toList());
}
Widget _tabBarView() {
return TabBarView(
controller: mController,
children: tabTitles.map((item) {
return Container(
color: _getColor(),
child: Center(
child: Text(item,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white)),
),
);
}).toList(),
);
}
Color _getColor() {
var random = new Random();
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
print(r);
print(g);
print(b);
return Color.fromARGB(255, r, g, b);
}
}
TabBarView
这里的children直接使用了Container显示效果,所以在切换的时候,并没有问题出现。但一般情况,我们都会为TabBarView的子类自定义一个Widget,并且会在这个Widget的 initState() 方法里面进行数据的初始化。这时候切换Tab,会发现界面又初始化了?~
(网传)Flutter中为了节约内存不会保存widget的状态,widget都是临时变量。所以,每次切换重修的时候,都会调用 initState() 方法
解决:
在对应的Widget里面的State类,继承AutomaticKeepAliveClientMixin抽象类,并且重写方法,返回true,强制widget不被销毁:
@override
bool get wantKeepAlive => true;
PS:widget在不显示也会强制保存在内存中,所以需要合理使用。
CustomUnderlineTabIndicator 自定义圆角指示器
最简单的,参考UnderlineTabIndicator(代码90行),对Ponit的画笔做了参数自定义。StrokeCap使用了.round的方式,就能实现。